湖南大學程序設計競賽新生賽(第二部分)

緊接着上一部分


Problem H:Kuangyeye’s Game

題目描述:
    Christmas Day is coming! To celebrate this great festival, Kuangyeye, a creative boy, wants to play a game with everyone. The rule is described as following: there are several balloons in the classroom, and you have a prop gun. To achieve a higher goal, you need to shoot as many balloons as you can with one bullet. Now you have to judge whether you can explosive all balloons with one shoot. In a rigorous word, there are n points on the plane, you need to judge if they are on the same line. In addition, the balloons may extremely tiny, so some of them may share the same coordinate.
輸入描述:
    The first line contains an integer n which indicates the number of balloons. The next n following lines contain two integers xi and yi each, which represent the X coordinate and the Y coordinate of i-th balloon respectively.
輸出描述:
    If you can explosive all balloons with one shoot, output “Yes”. Output “No” otherwise(without quotes).
樣例一:

輸入 輸出
2
1 1
-1 -1 Yes

說明:These two ballons are all on the line x-y=0.
樣例二:

輸入 輸出
3
1 2
2 1
3 3 No

說明:We can’t find a line which all these ballons on it.
備註1<=n<=1000, |xi|,|yi|<=1000。


題目大意:
給定平面上的n個點,判斷他們是否共線。
核心思路:

  • 在一個點和兩個點的情況下一定是共線的。
  • 在大於兩個點的時候,我們利用tanA=tanB來進行計算,這時我們已知前兩個點,tan=(y2-y1)/(x2-x1)。我們將x3,y3同樣利用等式求得,(y - y1) * (x2 - x1) - (y2 - y1) * (x - x1)=0的話就成立(此時不利用除法,爲了避免分母爲0)。
#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int n;
    int x, y;
    int x1, y1, x2, y2;
    while (cin >> n)
    {
        if (n == 1)
        {
            cin >> x1 >> y1;
            cout << "Yes" << endl;
        }
        else if (n == 2)
        {
            cin >> x1 >> y1 >> x2 >> y2;
            cout << "Yes" << endl;
        }
        else if (n >= 3)
        {
            bool flag = 0;
            cin >> x1 >> y1 >> x2 >> y2;
            for (int i = 3; i <= n; i++)
            {
                cin >> x >> y;
                if ((y - y1) * (x2 - x1) != (y2 - y1) * (x - x1)) //標記爲1則不成立
                    flag = 1;
            }
            if (flag)
                cout << "No" << endl;
            else
                cout << "Yes" << endl;
        }
    }
    return 0;
}

Problem I:Days passing

題目描述:
    LYX is the most handsome boy in HNU who likes math very much. One day his girlfriend JY asked LYX a simple problem: “Today is Sunday , what day of week will it be after 400^600 days, and what about 120^714?” LYX is very smart and answered: It will be Monday and Monday.
    Now LYX abstracts this problem as follows:
    ‘a’ denote the day of week today(‘a’ belong to {Mon, Tue, Wed, Thu, Fri, Sat, Sun}), what is the date after N^M (1<=N<10^10000,6<=M<10000) days ? Where M is exactly divided by 6.
輸入描述:
    There is 1 line, 1 string, 2 integers,
    there are a, N and M, separated by a space.
輸出描述:
    Output a string(Mon, Tue, Wed, Thu, Fri, Sat, Sun), the day of the week.
樣例一:

輸入 輸出
Sun 2 12 Mon

說明:The day(Sunday) after 2^12(4,096) days will be Monday.
樣例二:

輸入 輸出
Web 7 6 Web

說明:The day(Wednesday) after 7^6(117,649) days will be Wednesday.
樣例三:

輸入 輸出
Thu 1 6 Fri

說明:The day(Thursday) after 1^6(1) days will be Friday.


題目大意:
給出當前星期,求N^M天后是星期幾。
核心思路:

  • 由於題目輸入的限制(會爆long long),要利用高精度進行模擬取模運算。
  • 字符串模擬取模運算,算法思想:(a+b)%c=a%c+b%c。
//高精度取模運算
while(c=getchar())
{
   if(c==' ') break;
   N=(N*10+c-'0')%mod;//核心代碼,也可用string來寫讀入
}

#include <bits/stdc++.h>
using namespace std;

int fastPow(int n, int m)
{
    int res = 1;
    int base = n;
    while (m)
    {
        if (m & 1)
            res = (res * base) % 7;
        base = (base * base) % 7;
        m >>= 1;
    }
    return res;
}
int main()
{
    string s1, day;
    string tmpday[8] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    int xx, m, n = 0, ans;
    cin >> day >> s1 >> m;
    for (int i = 0; i <= 6; i++)
        if (day == tmpday[i])
            xx = i;//當天是星期幾?表示出來
    for (int i = 0; i < s1.length(); i++)
        n = (n * 10 + (s1[i] - '0')) % 7;
    n = fastPow(n, m);
    ans = (n + xx) % 7;
    cout << tmpday[ans] << endl;
    return 0;
}

Problem J:CET and miniskirt

題目概述:
    Xuxu is a student who likes English and skirt.Therefore, he has spent a lot of time preparing for CET. CET is a very important test, which determines the style of Xuxu’s skirt this year.
    Xuxu just finished the CET and got the standard answer after that. What’s more , if Xuxu gets zero, he will wear a skirt to the party, otherwise he will wear a suit(which is very disappointing). So Xuxu wants to know if it is possible for him to wear a skirt to the party. But unfortunately, he only remembers how many A, B, C and D he has written. Can you tell him weather he can wear a skirt in the party ?
輸入描述:
    The first line contains an integer n which indicates the number of questions.
    The second line contain a string s which indicates the answer of each question.The answer only contain the upper case letters ‘A’,‘B’,‘C’ and ‘D’.
    The third line contain four integer a,b,c,d indicates the number of A,B,C,D Xuxu has written.
輸出描述:
    If it’s impossible for Xuxu to wear skirt, output the minimum number of questions Xuxu may answer correctly, Otherwise output “orz”
樣例一:

輸入 輸出
4
ABCD
1 1 1 1 orz

說明:
It’s possible to get a zero if Xuxu has written BADC in CET.
樣例二:

輸入 輸出
3
AAA
2 1 0 0 2

說明:
It’s impossible to get a zero and the minium number of question Xuxu can answer correctly is 2.
備註:
n≤10^5,∣s∣=n,0≤a,b,c,d≤n,a+b+c+d=n。


題目大意:
結論:對於所有選項,寫下的選項個數 <= 答案中其他選項的個數都成立,則最低分爲0。否則最多存在一個寫下的選項個數 > 答案中其他選項,此時最低分爲這一選項的寫下的選項個數-答案中其他選項。

由於本博主水平有限,此題暫時不能AC,避免影響讀者的觀看理解效果,本博主將出題人的題解發布至此,抱歉。

核心思路:
在這裏插入圖片描述

#include <bits/stdc++.h>
using namespace std;
int a[4], b[4];
const int maxn = 1e5 + 50;
char s[maxn];
int main()
{
    int n;
    cin >> n;
    scanf("%s", s);
    assert(strlen(s) == n);
    for (int i = 0; i < n; ++i)
    {
        assert(s[i] >= 'A' && s[i] <= 'D');
        a[s[i] - 'A']++;
    }
    int ans = 0;
    for (int i = 0; i < 4; ++i)
    {
        cin >> b[i];
        assert(b[i] <= n && b[i] >= 0);
        if (n - a[i] < b[i])
            ans += b[i] + a[i] - n;
    }
    if (ans == 0)
        cout << "orz" << endl;
    else
        cout << ans << endl;
}


Problem K:Binbin’s treasure map

題目描述:
    Binbin is a clever boy who likes to wear a skirt. One day, he saw some beautiful skirts on Taobao, but he had not enough money, which made him sad.
    In order to make Binbin feel happy again, his’s friend Xu1024 gave him a treasure map. The treasure map is composed of three characters: ‘.’, ‘#’, ‘KaTeX parse error: Expected 'EOF', got '&' at position 4: '. &̲nbsp;&nbsp;&nbs…’ indicates that this position has 1 coin on it and is passablle.
    The locations outside the treasure map are all empty and passable.
    Binbin can move up, down, left, and right, but not at an angle.
    Firstly, Binbin can choose any grid as starting point.
    Because Binbin wanted to wear a skirt so much, he had a chance to teleport to a certain grid as another starting point.
    Binbin wanted to know how many coins he could eventually collect to buy skirts.
    Can you help him?
輸入描述:
    The first line of each group contains two numbers N and M,(1<=N, M<=500), representing the number of rows and the number of columns of treasure map.
    Then there are next N lines, each line contains M characters. which describe the terasure map.
輸出描述:
    Ouput a integer representingthe maxinum money Binbin would collected.
樣例一:

輸入 輸出
4 4
. $ . $
.##.
#$#.
.#.# 3

說明:Binbin can start at point(1,1) so he can collect 2 coins.

Then Binbin can teleport to point(3,2) so he can collect 1 coin.

Finally, Binbin would collect 3 coins.
樣例二:

輸入 輸出
4 4
.#$#
####
…$$
$$$$ 7

說明:Binbin can start at point(1,3) so he can collect 1 coin.

Then Binbin can teleport to point(3,2) so he can collect 6 coins.

Finally, Binbin would collect 7 coins.


題目大意:
給一個平面圖,上面有障礙物,平面圖以外的區域是相通的
可以選擇兩個起點,求收集到的錢幣數總和

由於本博主水平有限,此題暫時不能AC,避免影響讀者的觀看理解效果,本博主將出題人的題解發布至此,抱歉。

核心思路:
在這裏插入圖片描述

#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
#define PII pair<int,int>
char mp[maxn][maxn];
int dir_r[]={1,0,-1,0};
int dir_c[]={0,1,0,-1};
int n,m;
bool vis[maxn][maxn];
void bfs(int r,int c,int& cnt)
{
    queue<PII>q;
    q.push(make_pair(r,c));
    while(!q.empty())
    {
        PII u=q.front();q.pop();
        if(vis[u.first][u.second]||mp[u.first][u.second]=='#') continue;
        vis[u.first][u.second]=1;
        if(mp[u.first][u.second]=='$') ++cnt;
        for(int i=0;i<4;++i)
        {
            int nexr=u.first+dir_r[i],nexc=u.second+dir_c[i];
            if(nexr>=0&&nexr<=n+1&&nexc>=0&&nexc<=m+1) q.push(make_pair(nexr,nexc));
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i) scanf("%s",mp[i]+1);
    for(int i=0;i<=m+1;++i) mp[0][i]=mp[n+1][i]='.';
    for(int i=0;i<=n+1;++i) mp[i][0]=mp[i][m+1]='.';
    int max1=0,max2=0;
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            if(!vis[i][j]) 
            {
                int tmp=0;
                bfs(i,j,tmp);
                if(tmp>max1) max2=max1,max1=tmp;
                else if(tmp>max2) max2=tmp;
            }
        }
    }
    printf("%d",max1+max2);
    return 0;
}

Problem L:Xu1024’s treasure chest

題目描述:
    Xu1024 is a poor student. One day, Xu1024 found a treasure chest, but he didn’t have the password. The treasure chest said: if you want to get the treasure of the pirate king, you need to find three numbers A, B, C that the pirate king likes, making A < B < C and B^2 - A^2 = C^2 - B^2.
    Because Xu1024 has its own favorite number, he decided to take this number as A. now you need to help him find the other two numbers B and C to open the treasure chest. Because Xu1024 doesn’t like the number which is too large, the absolute value of the numbers A whill not be greater than 100,000,000.What’s more the absolute value of the numbers B and C you find shouldn’t exceed 1,000,000,000.
    Now I will tell you the number A. Please help Xu1024 find out the integer B and C satisfied that A < B < C and B^2 - A^2 = C^2 - B^2.
    If no answer can be found, output “-1”.
輸入描述:
    The first line contains an integer which is Xu1024’s favorite number.
輸出描述:
    If the answer exists, ouput two integers: B and C seperated by a space.
    If no answer can be found, output “-1”.
樣例一:

輸入 輸出
7 13 17

說明:13 ^ 2 - 7 ^ 2 = 17 ^ 2 - 13 ^ 2 = 120;
樣例二:

輸入 輸出
8599 50005 70193

說明:50005 ^ 2 - 8599 ^ 2 = 70193 ^ 2 - 50005 ^ 2 = 2426557224;


題目大意:
在這裏插入圖片描述
由於本博主水平有限,此題暫時不能AC,避免影響讀者的觀看理解效果,本博主將出題人的題解發布至此,抱歉。

核心思路:
在這裏插入圖片描述

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long aa, bb, cc;
    cin >> aa;
    if (aa == 0)
    {
        puts("-1");
        return 0;
    }
    aa = abs(aa);
    bb = 5 * aa;
    cc = 7 * aa;
    if (41 * aa < 1000000000)
    {
        cc = 41 * aa;
        bb = 29 * aa;
    }
    cout << bb << " " << cc << "\n";
    return 0;
}

Problem M:Buying Keys

題目描述:
    One day Xiao Ming is not happy because he has no idea about how to run out of his pocket money. At that moment, a mysterious man appears with a smile:“My keys are on sale, three yuan can buy a key, ten yuan can buy three keys.How many keys do you wanna buy?”
    Xiaoming is attracted by mysterious man and wants to spend all his money on buying keys. He doesn’t want keep any money at the end. At the same time, because of the heavy weight of keys, Xiaoming Hopes that he can buy as few keys as possible. At the beginning, Xiao Ming had n yuan. Can you tell Xiaoming the minimum number of keys he can bought if he runs out of his pocket money?If Xiaoming can’t run out of his money, please output “orz”.
輸入描述:
    The first line contains one integer n(1 ≤n ≤1e9), the pocket money Xiaoming have.
輸出描述:
    If Xiaoming can’t run out of his money, please output “orz”, otherwise output the minimum number of keys he can bought if he runs out of his money.
樣例一:

輸入 輸出
3 1

樣例二:

輸入 輸出
11 orz

說明:It’s impossible to run out of his money.


題目大意:
鑰匙3元一把十元三把,有n元錢,求剛好花完n元能買到的最小鑰匙數量。
核心思路:

  • 貪心算法+模擬
  • 因爲題幹知名買到最小鑰匙數量,則錢數/10代表最多買到的10元3個鑰匙的數量,若剩下的錢%3爲0的話就成立,此時爲最小的時候,若一直沒符合%3爲0,則就不成立。
#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int x;
    while (cin >> x)
    {
        int sum10 = 0, sum3 = 0;
        int tmp = x / 10, ans = 0;
        bool flag = 0;
        for (int i = tmp; i >= 0; i--) //10的數量
        {
            if ((x - (i * 10)) % 3 == 0)
            {
                ans = i * 3 + (x - (i * 10)) / 3;
                flag = 1;
                break;
            }
        }
        if (flag)
            cout << ans << endl;
        else
            cout << "orz" << endl;
    }

    return 0;
}

結束語

這次比賽雖然AC的題目很少,但是收穫很大,這兩篇題解是我花費了很長時間寫的,希望能幫助到大家!謝謝。ACM之路任重而道遠,奧利給。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章