GDUFS 2018信息学院程序设计新手赛(正式赛)题解

紧张刺激的新手赛结束了……有惊无险啊啊啊,虽然中途OJ炸了一次……很快就修复,感谢大家耐心的等待!

谢谢大家!!!

题解开始前,先向大家道个歉,题目还是很多误导人的地方,测评机崩了,导致很多人题没过。接下来都会一一解释……希望大家能理解……不过题目区分度还是达到了预期,有的同学表现也很抢眼。

 

Problem A: HELLO

Description

《绝地求生》(PUBG) 是一款战术竞技型射击类沙盒游戏 。 该游戏中,玩家需要在游戏地图上收集各种资源,并在不断缩小的安全区域内对抗其他玩家,让自己生存到最后。游戏《绝地求生》除获得G-STAR最高奖项总统奖以及其他五项大奖 ,还打破了7项吉尼斯纪录。小洪是这个游戏的狂热爱好者,就在他今天准备“吃鸡”的时候他的舍友小权突然提醒他今天是新手赛!他果断停止游戏,冲向实验室,输入了今天的比赛地址222.201.101.7,但是他发现登不上网站!于是他向你求救!

Input

输入只有一行,由不超过20个字符组成字符串,字符串仅由数字和字符“.”组成,判断其是否是今天的比赛网址。

Output

如果是输入的字符串是 "222.201.101.7" (不包括双引号),那么输出"Yes",否则输出 "No"

Sample Input

222.201.101.5

Sample Output

No

难易度:❤

题解:直接判断即可

坑点:注意字符数组判断要用strcmp,不能直接==,如果要直接==就用string类

#include<iostream>
using namespace std;
int main(){
    string url;
    cin>>url;
    if(url=="222.201.101.7")
    cout<<"Yes";
    else cout<<"No";
    return 0;
}

Problem B: ORZ

Description

《英雄联盟》(简称LOL)是由美国拳头游戏(Riot Games)开发、中国大陆地区腾讯游戏代理运营的英雄对战MOBA竞技网游。游戏里拥有数百个个性英雄,并拥有排位系统、符文系统等特色养成系统。《英雄联盟》还致力于推动全球电子竞技的发展,除了联动各赛区发展职业联赛、打造电竞体系之外,每年还会举办“季中冠军赛”“全球总决赛”“All Star全明星赛”三大世界级赛事,获得了亿万玩家的喜爱,形成了自己独有的电子竞技文化。小洪是英雄联盟的狂热爱好者,今天他决定学习三角形打野法。现在给你三条边,小洪可以花费一点法力让某一条边的长度增加1,请问要使得这三条边能组成三角形,最少需要多少法力?

Input

输入只有一行,三个数字A,B,C,分别代表三条边的长度。
所有数字范围为 (1~100)

Output

一个整数,代表最少需要多少法力,才能使得这三条边能组成一个三角形。

Sample Input

样例输入1:
3 4 5

样例输入2:
2 3 5

样例输入3:
100 10 10

Sample Output

样例输出1:
0

样例输出2:
1

样例输出3:
81

难易度:❤

题解:三角形定理,任意两边之和大于第三遍即可。

坑点:无

#include<bits/stdc++.h>
using namespace std;
const int MAXN=100005;
typedef long long ll;
 
int a[3];
 
int main(){
 
    scanf("%d%d%d",&a[0],&a[1],&a[2]);
    sort(a,a+3);
 
    if(a[0]+a[1]>a[2]){
        cout<<0<<endl;
    }
    else{
        cout<<a[2]-a[0]-a[1]+1<<endl;
    }
    return 0;
}

Problem C: NIGHTMARE

Description

《阴阳师》是由中国网易移动游戏公司自主研发的3D日式和风回合制RPG手游。2016年6月1日11:00,《阴阳师》开放安卓首测  ;同年9月2日,登陆ios平台于App Store首发 ;同年9月9日,阴阳师全平台公测 。游戏中的和风元素是以《源氏物语》的古日本平安时代为背景设计的。游戏剧情以日本平安时代为背景,讲述了阴阳师安倍晴明于人鬼交织的阴阳两界中,探寻自身记忆的故事 。小洪是阴阳师的狂热爱好者,今天他十连抽的时候抽到了3个SSR!于是他决定开个Party庆祝。在party中,有一个大Pizza~小洪要把它平均的分给N个小伙伴(包括他自己),那么小洪最少要切多少刀呢?我们假设 Pizza是圆的,并且不能伤害自己的小伙伴-_-||

Input

输入只有一行,一个数字N,代表Party中有N个小伙伴。
所有数字范围为 (1~100)

Output

要平均分的最少刀数

Sample Input

样例输入1:
1

样例输入2:
3

样例输入3:
4

Sample Output

样例输出1:
0

样例输出2:
3

样例输出3:
2

难易度:❤

题解:思维题,偶数输出N/2,奇数输出N,1输出0

坑点:样例都给出来了,无坑点

#include <bits/stdc++.h>
using namespace std;
int main(){
 
    int N;
    scanf("%d",&N);
    if(N==1)
        cout<<0<<endl;
    else if(N%2==1)
        cout<<N<<endl;
    else
        cout<<N/2<<endl;
    return 0;
}

Problem D: GAME

Description

《糖果传奇》是由King开发的一款微策略消除手游,于2014年8月发行。游戏设置了超过500关的关卡,在游戏中,玩家可以通过三个或三个以上的糖果以不同方式的连接消除得分,碰撞开不同的障碍物完成任务。小洪是糖果传奇的狂热爱好者。他和他的女朋友都特别喜欢这个游戏,现在他们相约在某个地方一起玩这个游戏。我们假设他们的家在一个X轴上。小洪的家在 X1=a的位置,他女朋友在X2=b的位置。每个人都可以在X轴上行走任意多次。当一个人移动一次的时候,他的疲劳值会改变,疲劳值改变的规则如下:
第一次移动疲劳值增加1,第二次移动疲劳值增加2,第三次移动疲劳值增加3……举个例子,小洪往右走了一步,再往左走了一步(回到初始位置),再往右走了一步,那么他一共走了三步,那么他的疲劳值为 1+2+3=6.

他们俩人会在某个整点相遇,请你帮他们计算,他们要相遇的最少的疲劳值之和。

Input

输入有两行,第一行1数字 a,代表小洪的初始位置
第二行一个数字b,代表他女朋友的初始位置
所有的数字范围为 (1~1000)

Output

让他们相遇的最少的疲劳值之和。

Sample Input

样例输入1:
3
4

样例输入2:
101
99

样例输入3:
5
10

Sample Output

样例输出1:
1

样例输出2:
2

样例输出3:
9

难易度:❤❤

题解:简单思维,实际上,平均走是最优的,所以我们只要算出中点,然后直接计算即可。

坑点:看你能不能想得出来。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <memory.h>
#include <bitset>
#include <map>
#include <deque>
#include <math.h>
#include <stdio.h>
using namespace std;
int main()
{
    int a,b;
    cin>>a>>b;
    int m=(a+b)/2;
    if(a>b)
        swap(a,b);
    long long int ans=0;
    for(int i=1;i<1000;i++){
        if(a==m)
            break;
        ans+=i;
        a++;
    }
    for(int i=1;i<1000;i++){
        if(b==m)
            break;
        ans+=i;
        b--;
    }
    cout<<ans<<endl;
    return 0;
}

Problem E: ROAL

Description

《osu!》是一款基于《押忍!战斗!应援团》、《精英节拍特工》和《太鼓达人》等商业游戏改编的免费同人音乐游戏,由Peppy (Dean Herbert)开发制作。小洪是osu狂热爱好者。但是他今天想打锄大地,在他的世界中。牌是没有花色的。现在给你5张牌(1~13),要你判这五张牌能否组成顺子,葫芦,金刚
顺子:五张牌是连续的,如1 2 3 4 5,5 6 7 8 9,9 10 11 12 13,10 11 12 13 1是顺子,但是11 12 13 1 2和 12 13 1 2 3和13 1 2 3 4 不算顺子。
葫芦:三张带一对。如,1 1 1 2 2,5 5 5 6 6,11 11 11 13 13.
金刚:四张带一个。如1 1 1 1 2,13 13 13 13 1.

Input

输入只有一行,每行5个数字,代表5张牌,数字的范围为(1~13)题目保证数字出现的次数不会超过4次。

Output

如果是顺子输出“shunzi”
如果是葫芦输出“hulu”
如果是金刚输出“jingang”
如果都不是输出“lanpai”

Sample Input

样例输入1:
10 11 12 1 13

样例输入2:
5 5 5 5 4

样例输入3:
5 5 5 4 4

样例输入4:
11 12 13 1 2

Sample Output

样例输出1:
shunzi

样例输出2:
jingang

样例输出3:
hulu

样例输出4:
lanpai

难易度:❤❤

题解:无

坑点:仔细读题,另外善用排序。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <memory.h>
#include <set>
#include <map>
#include <deque>
#include <math.h>
#include <stdio.h>
using namespace std;
int main()
{
    int a[5];
    for(int i=0;i<5;i++)
        scanf("%d",&a[i]);
    sort(a,a+5);
 
    map<int,int> s;
    for(int i=0;i<5;i++)
        s[a[i]]++;
 
    if((a[0]==a[1]-1&&a[1]==a[2]-1&&a[2]==a[3]-1&&a[3]==a[4]-1)||(a[0]==1&&a[1]==10&&a[2]==11&&a[3]==12&&a[4]==13))
        printf("shunzi\n");
    else if(s.size()==2&&(s.begin()->second==2||s.begin()->second==3))
        printf("hulu\n");
    else if(s.size()==2&&(s.begin()->second==1||s.begin()->second==4))
        printf("jingang\n");
    else
        printf("lanpai\n");
 
 
    return 0;
}
 

Problem F: OMG

Description

《中国式家长》是一款由墨鱼玩游戏开发的模拟养成游戏,游戏已经上架steam、wegame于2018年9月29日正式发售。
《中国式家长》是一款现实主义的模拟游戏,游戏模拟从出生到高考的整段过程,探讨中国孩子与家长之间的关系。2018年10月,《中国式家长》的游戏在网络上引发热议。该游戏销售刚满一个月,已经在一家知名游戏商城上取得全球周销量排行第2名。小洪是中国式家长的狂热爱好者。今天他决定让他的孩子小洲上清华!已知小洲高考的分数,请你计算一下他某几科科目的分数和!我们假设在游戏的世界中,高考科目有很多,然后小洪会让你查询某个区间的分数和。

Input

输入有多行,第一行两个数字N和Q,代表游戏世界中有N个科目和小洪会问你Q个问题。第二行包括N个数字,由空格隔开,每个数字代表小洲一科的高考分数Ai。
接下来有Q行,每行包括两个数字L和R,代表小洪要你告诉他这N个科目中,从第L个到第R个科目的分数的和
(1<=Ai<=100)
(1<=N<=100000)
(1<=Q<=100000)
(1<=L<=R<=N)

Output

对于每个查询,输出一个数字,代表该次查询的分数和。每个数字占一行。

Sample Input

样例输入1:
5 3
1 2 3 4 5
1 2
2 4
1 5

样例输入2:
5 5
100 99 98 1 2
1 1
2 2
4 5
1 5
3 5

Sample Output

样例输出1:
3
9
15

样例输出2:
100
99
3
300
101

难易度:❤❤❤

题解:很多人以为是简单题,然后直接算,其实这样的时间复杂度是不可以接受的,所以很多人都收到了Runtime Error和Time Limited  Exceed错误。所以我们要优化我们的算法。这里引入一个前缀和的概念。假设前i项的和为sum[i],那么我们要计算L~R的和就只需要一个公式,sum[R] - sum[L-1] 即可。为啥这样可以,自己思考。然后对于每一个sum[i]我们预处理出来即可。

坑点:暴力算会超时

#include<bits/stdc++.h>
using namespace std;
int a[1000005];
int sum[1000005];
int main()
{
    int N,Q;
    scanf("%d%d",&N,&Q);
    for(int i=1;i<=N;i++){
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    int L,R;
    while(Q--){
        scanf("%d%d",&L,&R);
        printf("%d\n",sum[R]-sum[L-1]);
    }
    return 0;
}

Problem G: CRAWLING

Description

《太吾绘卷》是ConchShip Games研发的一款以神话和武侠为题材的独立游戏。玩家将扮演神秘的“太吾氏传人”。
在《太吾绘卷》的世界中,你除了需要扮演神秘的“太吾氏传人”,还将以不同的处世立场——或善、或恶、或中庸——投身于纷繁复杂的江湖之中。你不仅可以拜访世界各地的武林门派,学习种类繁多的功法绝艺;还可以与人义结金兰,或结下血海深仇;不仅可以兴建自己的村庄,经营各种产业;还可以与自己的挚爱生儿育女,缘定三生;直到你终于面对太吾氏的宿敌,击败相枢剑冢,决定世界的命运!小洪是太吾绘卷的狂热爱好者,同时他也很喜欢研究集合问题,最近他在研究邪恶集合,所谓邪恶集合,就是如果这个集合里不存在的最小的非负整数是X,那么这个集合就是邪恶的。现在小洪手里有一个集合,他想把他变成邪恶集合,每一步小洪可以删掉集合里一个数,或者往集合里添加添加一个数,请问小洪最少需要多少步,才能使得这个集合变成邪恶集合!

Input

输入有两行,第一行两个数字 N,X,代表初始集合的大小 ,和题目中的X
第二行包括N个各不相同的数字,代表集合初始的N个数字
所有的数字范围为 (1~10000)

Output

要把这个集合变成邪恶集合的最少步数

Sample Input

样例输入1:
5 3
0 4 5 6 7

样例输入2:
5 1
1 2 3 4 5

样例输入3:
1 0
0

Sample Output

样例输出1:
2

样例输出2:
2

样例输出3:
1

难易度:❤❤❤

题解:逻辑题,实际上我在样例解释中已经解释得很清楚了。我们只需要计算缺了多少个数和多了多少个数即可。

坑点:注意非负整数包括0.

#include<bits/stdc++.h>
using namespace std;
int a[200];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>a[i];
    int i;
    int num=0;
    //计算集合里比M小的数有多少个,直接枚举每一个数看看集合里有没有
    for(i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(a[j]==i){
                num++;
            }
        }
    }
    //看看有没有跟M大小一个的数,有的话需要一个删除操作。这里aaa要么0要么1.
    int aaa=0;
    for(int j=0;j<n;j++){
        if(a[j]==m){
            aaa++;
        }
    }
 
    //答案
    cout<<m-num+aaa<<endl;
 
    return 0;
}

Problem H: KINGDOM

Description

《王者荣耀》是由腾讯游戏天美工作室群开发并运行的一款运营在Android、IOS、NS平台上的MOBA类手机游戏,于2015年11月26日在Android、IOS平台上正式公测。小洪是王者荣耀的狂热爱好者,但是他最近玩腻了,决定返璞归真,折纸飞机玩。他还邀请了他的ACM的小伙伴们一起玩耍。已知每张纸能够折S个纸飞机,现在有K个小伙伴,每个小伙伴要折N个纸飞机。但是纸只能一包一包的买,已知每包纸有包含P张纸。现在要把纸分给每一个小伙伴,使得每个小伙伴都有足够的纸去折属于他的N个纸飞机,那么请问,他们最少要买多少包纸?注意,纸是不能共享的喔~

Input

输入只有一行,每行4个数字,用空格隔开,分别为  K,N,S,P,每个数字所代表的的意思见上述题面。
所有数字范围为 (1~10000)

Output

一个数字,代表最少要买多少包纸。

Sample Input

样例输入1:
5 3 2 3

样例输入2:
5 3 100 1

Sample Output

样例输出1:
4

样例输出2:
5

难易度:❤❤

题解:小学数学题,直接算即可。

坑点:注意取整问题,和变量名字别搞错

#include<bits/stdc++.h>
using namespace std;
int k,n,s,p;
int main()
{
    cin>>k>>n>>s>>p;
    cout<<(int)(ceil((int)(ceil(n/(double)(s)))*k/(double)(p)))<<endl;
    return 0;
}

Problem I: NECKLACE

Description

Codeforces是一家为计算机编程爱好者提供在线评测系统的俄罗斯网站。该网站由萨拉托夫国立大学的一个团体创立并负责运营。
小洪是Codeforces的狂热爱好者,今天他决定打CF,今天CF的签到题非常简单,他决定让你们来做~幸运的是,小洪已经帮你们翻译好题目了。已知一个字符串,让你求这个字符串的所有不同的非空子串的长度乘以该子串出现的次数的和。以下是具体解释

子串:串中任意个连续的字符组成的子序列称为该串的子串,比如有一个串 ababacab,以下串都是他的子串
ab(出现了三次),a(出现了四次),aba(出现了两次),bab,ababcab(出现了一次)等
不同的子串:比如有一个串 ababcab,以下串都是他不同的子串
ab,a,aba,bab,ababcab,c等
子串的长度:即该子串的字符个数,如aba的长度为3,a的长度为1.

Input

输入只有一行,包括一个只由小写字母组成的字符串
字符串的长度为 (1~1000)

Output

这个字符串的所有不同的非空子串的长度乘以该子串出现的次数的和

Sample Input

样例输入1:
a

样例输入2:
aba

样例输入3:
abab

Sample Output

样例输出1:
1

样例输出2:
10

样例输出3:
20

HINT

对于aba他的所有不同的子串有

a(出现了两次)

b(出现了一次)

ab(出现了一次)

ba(出现了一次)

aba(出现了一次)

所以总的答案为 1*2+1*1+2*1+2*1+3*1 = 10

对于abab,他的所有不同的子串有

a(出现了两次)

b(出现了两次)

ab(出现了两次)

ba(出现了一次)

aba(出现了一次)

bab(出现了一次)

abab(出现了一次)

所以答案为 1*2+1*2 +2*2+2*1+3*1+3*1+4*1 = 20

难易度:❤❤❤❤

题解:题目要求的是,一个字符串中,所有不同的子串出现的次数乘以他的长度的和。乍一看很难的样子,实际上我们只需要稍作分析,就会发现其实是一个简单题。我们把不同的子串出现的次数这个限制去掉,改成所有子串出现的次数乘以他的长度的和。那么我们就会发现,每一个子串出现的次数都是1次。所以答案就会变成一个很简单的公式了。我们假设原字符串长度为N,那么答案就是,长度为N的子串有一个,长度为N-2的子串有两个,长度为N-3的子串有三个。。。然后直接计算出和即可。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <memory.h>
#include <set>
#include <map>
#include <deque>
#include <math.h>
#include <stdio.h>
using namespace std;
int main()
{
 
    string str;
    cin>>str;
    int N=str.length();
    int sum=0;
    for(int i=1;i<=N;i++)
    {
        sum+=i*(N-i+1);
    }
    printf("%d\n",sum);
 
 
    return 0;
}

Problem J: BECAUSE

Description

CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。CTF起源于1996年DEFCON全球黑客大会,以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式。发展至今,已经成为全球范围网络安全圈流行的竞赛形式,2013年全球举办了超过五十场国际性CTF赛事。小洪是ACM的狂热爱好者,但是他也业余打打CTF,CTF涉及密码学,在密码学中素数是非常重要的一个东西,今天小洪在打CTF的时候,遇到了一个非常有意思的题目,他决定用ACM的方法去解决它,题目大意是这样的,给你一个正整数N,要你求出所有满足方程 1/X + 1/Y = 1/N 的正整数解的个数,即X>0,Y>0的解的个数。小洪已经解出了这道题目,他决定考考你,看看你是否也能解出来~

Input

输入有包括一行,一个正整数N
所有的数字范围为 (1<=N<=1000000000)(1后面9个0)

Output

满足方程 1/X + 1/Y = 1/N 的正整数解的个数,其中X<=Y

Sample Input

样例输入1:
1

样例输入2:
3

样例输入3:
20180101

样例输入4:
1000000000

Sample Output

样例输出1:
1

样例输出2:
2

样例输出3:
5

样例输出4:
181

难易度:❤❤❤❤❤❤❤❤

解题思路:这实际上是一道数学题,直接百度1/X + 1/Y = 1/N 即可找到详细题解。https://www.cnblogs.com/GHzz/p/8644625.html

坑点:要会因式分解公式

#include<iostream>
using namespace std;
typedef long long int ll;
int main(){
    ll n;
    cin>>n;
    n=n*n;
    ll sum = 1;
    for(ll i = 2; i*i <= n; i++){
        int cou = 0;
        if(n%i==0){
            cou = 1;
            n /= i;
            while(n%i==0){
                cou++;
                n /= i;
            }
        }
        if(cou != 0){
            sum = sum*(cou+1);
        }
    }
 
    if(n != 1){
        sum = sum*2;//剩下一个质数(1+1)
    }
    if(sum==1 && n==1){
        sum = 1;
    }
 
    cout<<(sum-1)/2+1<<endl;
 
    return 0;
}
发布了401 篇原创文章 · 获赞 61 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/lzc504603913/article/details/84634417