湖南大学程序设计竞赛新生赛(第二部分)

本文精选了多个算法竞赛题目,包括共线判断、日期计算、考试分数预测、宝藏地图探索等,通过详细解析核心思路,提供了高效算法实现,旨在帮助读者深入理解算法设计与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

紧接着上一部分


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 -1Yes

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

输入输出
3
1 2
2 1
3 3No

说明: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 12Mon

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

输入输出
Web 7 6Web

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

输入输出
Thu 1 6Fri

说明: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 1orz

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

输入输出
3
AAA
2 1 0 02

说明:
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”.
样例一:

输入输出
713 17

说明:13 ^ 2 - 7 ^ 2 = 17 ^ 2 - 13 ^ 2 = 120;
样例二:

输入输出
859950005 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.
样例一:

输入输出
31

样例二:

输入输出
11orz

说明: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之路任重而道远,奥利给。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值