中南大学2019年ACM寒假集训前期训练题集(入门题)


A: 漫无止境的八月

Description

又双叒叕开始漫无止境的八月了,阿虚突然问起长门在这些循环中团长哪几次扎起了马尾,他有多少次抓住了蝉等等问题,长门一共回复n个自然数,每个数均不超过1500000000(1.5*10^9)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。

Input

第1行是整数n,表示回复的自然数的个数。n<=1e6
第2~n+1行每行一个自然数。

Output

包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

Sample Input

8
2
4
2
4
5
100
2
100

Sample Output

2 3
4 2
5 1
100 2

题意:给你n个数,你要找到输入的每个数出现了多少次,并从小到大的输出该个数对应的值和出现的次数。
解法:这题我们可以利用map来存储,我们知道map的key,value在输入进去在之后map会自动的以key值进行排序,所以我们利用这个性质,key存放对应的数值,value存放对应的次数,然后输出map就可以了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map>
using namespace std; int n; map<int,int>m; int main() { scanf("%d",&n); m.clear(); int x; while(n--) { scanf("%d",&x); if(m.count(x)==0) m[x]=1; else m[x]++; } map<int,int>::iterator iter; for(iter=m.begin();iter!=m.end();iter++) printf("%d %d\n",iter->first,iter->second); return 0; } /********************************************************************** Problem: 2204 User: jk1601zr Language: C++ Result: AC Time:148 ms Memory:2424 kb **********************************************************************/

B: Magia

Description

吼姆啦酱来救被变成魔女的纱耶香攻击的小圆辣!魔境背景中的指挥家指挥着这场表演的音乐,吼姆啦酱发现一个规律,如果过一串音符是回文的,那么这串音符会实物化来攻击她,现在给出一段音符,判断它是否是回文的。一个左右对称的自然数称为回文数,即这个数从左往右读与从右往左读是一样的,如121,686,13731,8668等都是回文数。

Input

输入一个int范围内的自然数N,判断它是否是回文数。如果是就输出这个回文数,若不是则输出-1。

Output

只有一行,N是回文数,就输出N,不是就输出-1。

Sample Input

686

Sample Output

686

题意:判断回文。
解法:直接存在字符串数组里面,感觉会方便比较吧,看个人习惯。然后区分奇数偶数对应的判断就行了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map>
using namespace std; const int maxn=1000; char s[maxn]; int main() { scanf("%s",s); int len=strlen(s); bool flag=false; if(len%2==1) { int temp=len/2; for(int i=0;i<temp;i++) { if(s[i]!=s[len-i-1]) { flag=true; break; } } if(flag) printf("-1\n"); else { for(int i=0;i<len;i++) printf("%c",s[i]); printf("\n"); } } else { int temp=len/2; for(int i=0;i<=temp;i++) { if(s[i]!=s[len-i-1]) { flag=true; break; } } if(flag) printf("-1\n"); else { for(int i=0;i<len;i++) printf("%c",s[i]); printf("\n"); } } return 0; } /********************************************************************** Problem: 2205 User: jk1601zr Language: C++ Result: AC Time:4 ms Memory:2024 kb **********************************************************************/

C: 长门的运动会

Description

运动会,好开心~

CSU (California State University) 正在举行一场特殊的接力跑比赛,比赛在环形跑道上进行,同一支队伍的所有人从同一个位置向相同的方向出发,当需要接力的两个人再次相遇时,他们就要交接棒。最后总成绩是以队伍跑的总路程计算的。

接力比赛

现在接力的第一棒在Nagato手中,需要把它交给Kyon。在长度为C的环形跑道上,他们出发了!Nagato以速度A匀速跑动,Kyon以速度B匀速跑动。他们在经过多长时间后可以再次相遇?

Input

多组数据,第一行为一个整数T (1 ≤ T ≤ 106),表示数据组数。

之后每行是一组数据,有三个整数C, A, B (1 ≤ C, A, B ≤ 109, A ≠ B),分别表示环形跑道的长度,Nagato的速度和Kyon的速度。

Output

每行输出一个数,表示再次相遇所需的时间。绝对误差或相对误差小于10−5则认为是正确的。

Sample Input

2
3 1 2
5 10 7

Sample Output

3.00000000
1.66666667

题意:两个人从同一起点一起跑,看谁先比另一个人多跑一圈。
解法:求出两个人速度的差值,然后简单的物理计算。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map>
using namespace std; const int maxn=1000; int T; int c,a,b; int main() { scanf("%d",&T); while(T--) { scanf("%d %d %d",&c,&a,&b); int temp=abs(a-b); double ans=c*1.0/(temp); printf("%.8f\n",ans); } return 0; } /********************************************************************** Problem: 2158 User: jk1601zr Language: C++ Result: AC Time:316 ms Memory:2024 kb **********************************************************************/

D: 剪刀石头布

Description

 

现在一共有N个人(分别记为1, 2, …, N)在玩剪刀石头布,如果知道他们每个人都出了什么,你能找出来谁是winner吗?

当且仅当一个人可以赢其他所有人时,才称这个人是winner。

我们将剪刀记作2,石头记作0,布记作5,那么胜负关系就应当是2能赢5,5能赢0,0能赢2。

 

Input

 

输入数据的第一行包含一个整数T ( 1 <= T <= 150),表示接下来一共有T组测试数据。

每组测试数据的第一行包含一个整数N (2 <= N <= 100000)表示一共有N个人在玩剪刀石头布,接下来一行一共有N个数,每个数均为0、2或5中的某一个,依次描述了这N个人分别出了什么,其中第i个整数描述了第i个人出了什么。

 

Output

 

对于每组数据,用一行输出一个整数表示winner是第几个人([1, N]中的某个整数)。

如果不存在winner,则用一行输出“No winner”(不包括引号)。

 

Sample Input

3
3
5 5 2
3
2 0 0
3
0 2 5

Sample Output

3
No winner
No winner

题意:模拟剪刀石头布的游戏,我们知道三个模式当且仅当出现两种,并且一个能打败另一个的时候才会有winner。

#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> #include <set>
using namespace std; const int maxn=100005; int T; int n,x; //struct Node //{ // int val; // int cnt; //};
int a[3],pos[3]; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<3;i++) a[i]=pos[i]=0; for(int i=0;i<n;i++) { scanf("%d",&x); if(x==2) { a[0]++;pos[0]=i+1; } else if(x==0) { a[1]++;pos[1]=i+1; } else if(x==5) { a[2]++;pos[2]=i+1; } } // if(a[0]!=0&&a[1]!=0&&a[2]!=0) // printf("No winner\n");
        if(a[0]==1&&a[1]==0) printf("%d\n",pos[0]); else if(a[1]==1&&a[2]==0) printf("%d\n",pos[1]); else if(a[2]==1&&a[0]==0) printf("%d\n",pos[2]); else printf("No winner\n"); } return 0; } /********************************************************************** Problem: 1202 User: jk1601zr Language: C++ Result: AC Time:0 ms Memory:0 kb **********************************************************************/

E: 全场最水题之陈兴老师与比赛

Description

大家都知道ACM比赛罚时很重要。比如说你做A题要10分钟,B题要15分钟,如果先做A题再做B题,那么在ranking上的时间就是10 + (10)+ 15 = 35。如果先做B题再做A题总罚时就是15+(15)+

10=40.现在陈兴老师要做一场比赛,比赛有n道题, 总时间是300分钟。我们的陈兴老师仅仅看题目就可以知道他做每道题需要的时间。比如一般的比赛,陈兴老师做第一题需要1分钟,第二题2分钟,依此类推,陈兴老师只需要66分钟就可以AK一场11道题的比赛。PS: 陈兴老师做题都是1Y,膜拜陈兴老师Orz!

 

Input

第一行是一个数字n  0<n<=25

第二行是n个数字,第i个数字代表陈兴老师出编号为i的题所需要的时间 ti( 0 < ti <= 80)。

 

Output

第一行输出陈兴老师的出题数和Penalty(总时间)

以下按照顺序输出陈兴老师出题的顺序,每行一个编号。(详见输出样例)PS:时间一样的按编号升序输出。

 

Sample Input

3
1 2 3
4
1 2 3 4
6
60 60 60 60 60 60

Sample Output

3 10
1
2
3
4 20
1
2
3
4
5 900
1
2
3
4
5
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map>
using namespace std; struct Node { int t; int num; }node[30]; int cmp(Node a,Node b) { if(a.t!=b.t) return a.t<b.t; else
        return a.num<b.num; } int main() { int n,i,j,sum,k; while(cin>>n) { for(i=0;i<n;i++) { cin>>node[i].t; node[i].num=i+1; } sort(node,node+n,cmp); sum=0;k=0; for(i=0;i<n;i++) { if(k+node[i].t>300) break; k+=node[i].t; } int temp1=i,temp2=i; for(i=0;i<temp1;i++) { sum+=node[i].t*(temp2--); } cout<<temp1<<" "<<sum<<endl; for(i=0;i<temp1;i++) { cout<<node[i].num<<endl; } } return 0; } /********************************************************************** Problem: 1315 User: jk1601zr Language: C++ Result: AC Time:320 ms Memory:2024 kb **********************************************************************/

F: 字符画

Description

读入 w,请输出 2018 的字符画,两个数字之间有 w 个空格。具体格式请参考样例输出。

  • 1 ≤ w ≤ 2018

Input

输入文件只包含 1 个整数 w.

Output

输出 5 行,每行 12 + 3w 个字符(只包含 o 和 . 两种,字符画的部分用 o,空格的部分用 .),以换行符结尾。

Sample Input

2

Sample Output

ooo..ooo..ooo..ooo
..o..o.o...o...o.o
ooo..o.o...o...ooo
o....o.o...o...o.o
ooo..ooo..ooo..ooo

直接模拟就行。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map>
using namespace std; int n; int main() { scanf("%d",&n); printf("ooo"); for(int i=0;i<n;i++) printf("."); printf("ooo"); for(int i=0;i<n;i++) printf("."); printf("ooo"); for(int i=0;i<n;i++) printf("."); printf("ooo"); printf("\n"); printf("..o"); for(int i=0;i<n;i++) printf("."); printf("o.o"); for(int i=0;i<n;i++) printf("."); printf(".o."); for(int i=0;i<n;i++) printf("."); printf("o.o"); printf("\n"); printf("ooo"); for(int i=0;i<n;i++) printf("."); printf("o.o"); for(int i=0;i<n;i++) printf("."); printf(".o."); for(int i=0;i<n;i++) printf("."); printf("ooo"); printf("\n"); printf("o.."); for(int i=0;i<n;i++) printf("."); printf("o.o"); for(int i=0;i<n;i++) printf("."); printf(".o."); for(int i=0;i<n;i++) printf("."); printf("o.o"); printf("\n"); printf("ooo"); for(int i=0;i<n;i++) printf("."); printf("ooo"); for(int i=0;i<n;i++) printf("."); printf("ooo"); for(int i=0;i<n;i++) printf("."); printf("ooo"); printf("\n"); return 0; } /********************************************************************** Problem: 2163 User: jk1601zr Language: C++ Result: AC Time:8 ms Memory:2024 kb **********************************************************************/

H: joghs

Description

编号为1、 2、 3、 …、 n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。从指定编号为1的人开始,按顺时针方向自1开始报数,报到指定值m时停止报数,报第m的人出列,并将他的密码作为新的m值,从他在顺时针方向的下一个人开始,重新从1开始报数,如此类推,直至所有的人全部出列为止。输入n(n<=1000),m(m<=30000)及密码值(<=10000),试设计一个程序求出列顺序。

Input

有二行,第一行,N和M,第二行,N个小于等于10000的密码值,中间用空格隔开。

Output

只有一行,就是出列的顺序,编号间以空格隔开。

Sample Input

6 7
1 4 2 8 5 7

Sample Output

1 2 6 3 5 4

题意:约瑟夫环问题,但是要注意m值是在变化的,开始看题没注意。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> #include <vector> #include <list>
using namespace std; const int maxn=1005; int n,m; int a[maxn]; int main() { scanf("%d %d",&n,&m); list<int>l; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); l.push_back(i); } list<int>::iterator it; int cnt=1; for(it=l.begin();l.size()!=1;) { if(cnt++==m) { printf("%d ",*it); m=a[*it]; it=l.erase(it); cnt=1; } else it++; if(it==l.end()) it=l.begin(); } printf("%d\n",*l.begin()); return 0; } /********************************************************************** Problem: 2053 User: jk1601zr Language: C++ Result: AC Time:24 ms Memory:2028 kb **********************************************************************/

G: N个数字求和

这题数据有锅,待补。

I: 英文单词

Description

编写程序,读入一行文本,文本是一个长度不超过255的英文句子,单词之间有一个或一个以上的空格,输出:
①统计单词的个数;
②一个对应的英文句子,其中原句中的所有小写字母均转换成大写字母,大写字母转换成小写字母;
③删除所有空格符后对应的句子。

Input

只有一行,就是一个英文句子

Output

有三行,第一行单词的个数,第二行,转换了大小写的英文句子,第三行删除空格的句子。

Sample Input

Who are you?

Sample Output

3
wHO ARE YOU?
Whoareyou?

题意:直接模拟就行,但是要注意这个字符串的读入,要用到getline,不然空格读入不了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map>
using namespace std; const int maxn=300; char s[maxn]; int main() { cin.getline(s,256); int len=strlen(s); // cout<<len<<endl;
    int cnt=0; for(int i=0;i<len;i++) { if(s[i]==' '&&((s[i+1]>='a'&&s[i+1]<='z')||(s[i+1]>='A'&&s[i+1]<='Z'))) cnt++; } if(s[0]!=' ') cnt++; printf("%d\n",cnt); for(int i=0;i<len;i++) { if(s[i]>='a'&&s[i]<='z') printf("%c",s[i]-32); else if(s[i]>='A'&&s[i]<='Z') printf("%c",s[i]+32); else printf("%c",s[i]); } printf("\n"); for(int i=0;i<len;i++) { if(s[i]==' ') continue; else printf("%c",s[i]); } printf("\n"); return 0; } /********************************************************************** Problem: 2050 User: jk1601zr Language: C++ Result: AC Time:4 ms Memory:2024 kb **********************************************************************/

J: Num

Description

编一程序,输入正整数N(N在2~32767之间), 求它的最大质因子(包括它本身)。

Input

只有一行,就是正整数N

Output

所求的最大质因子

Sample Input

7

Sample Output

7
题意:题面就很清楚了。
解法:预处理出2~32767所有的质数,然后从大到小对应的判断就行了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> #include <set>
using namespace std; const int maxn=323767; set<int>s; int check[maxn]; int n; void init() { memset(check,0,sizeof(check)); for(int i=2;i<=maxn;i++) { if(!check[i]) s.insert(i); for(int j=i+i;j<=maxn;j+=i) check[j]=1; } } int main() { init(); scanf("%d",&n); for(int i=n;;i--) { if(s.count(i)&&n%i==0) { printf("%d\n",i); break; } } return 0; } /********************************************************************** Problem: 2051 User: jk1601zr Language: C++ Result: AC Time:32 ms Memory:4608 kb **********************************************************************/

K: 时间旅行

Description

假设 Bobo 位于时间轴(数轴)上 t0 点,他要使用时间机器回到区间 (0, h] 中。

当 Bobo 位于时间轴上 t 点,同时时间机器有 c 单位燃料时,他可以选择一个满足 xhhc⌈xh⌉⋅h≤c 的非负整数 x, 那么时间机器会在 [0, x]中随机整数 y,使 Bobo 回到 (t − y) 点,同时消耗 y 单位燃料。 (其中 ⌈ ⋅ ⌉ 表示上取整)

因为时间机器的随机性,对于给出的参数 h 和时间机器剩余燃料 c,Bobo 想知道能够保证回到区间 (0, h] 中的 t0 的最大值。

  • 1 ≤ h ≤ 109
  • 0 ≤ c ≤ 109
  • 数据组数不超过 105.

Input

输入文件包含多组数据,请处理到文件结束。

每组数据包含 2 个整数 h 和 c.

Output

对于每组数据输出 1 个整数表示 t0 的最大值。

Sample Input

100 99
100 100
100 149

Sample Output

100
101
150

模拟,读清题意就可以了。
#include <iostream> #include <stdio.h> #include <string> #include <string.h> #include <algorithm> #include <math.h> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <list>
using namespace std; typedef long long LL; const int INF=0x3f3f3f3f; const double eps=1e-8; const double pi=acos(-1.0); const int MOD=10056; const int maxn=2016; int h,c; int main() { while(scanf("%d %d",&h,&c)!=EOF) { if(h>c) printf("%d\n",h); else printf("%d\n",c+1); } return 0; } /********************************************************************** Problem: 2165 User: jk1601zr Language: C++ Result: AC Time:112 ms Memory:2024 kb **********************************************************************/

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM