长沙理工大学第十二届ACM大赛
A 时间限制:1秒 空间限制:131072K
题目描述
在云塘校区,有一个很适合晒太阳的地方————年轮广场
年轮广场可以看成n个位置顺时针围成一个环。
这天,天气非常好,Mathon带着他的小伙伴们出来晒太阳。他们分别坐在A[i]位置上,每个位置上保证最多只有1个小伙伴。现在Mathon想让大家集合玩狼人杀,所以想选择一个位置集合,之后所有的人顺时针或逆时针移动到那里去,每移动两个相邻的位置需要1个单位时间,小伙伴们都很有素质所以不会插近路踩草坪,只会沿着位置走。
Mathon想越快集合越好,于是他在群里发了QQ消息告诉大家集合位置,假设所有人都立刻接到了消息,然后都以最优的方法往集合位置移动。
要把所有人集合到一个位置最少需要多少时间?
输入描述:
多组输入 每组数据第一行输入n,m(1<=n,m<=1000),n表示年轮广场上位置的个数,m表示Mathon以及他的小伙伴总人数 第二行m个数,第i个A[i](1<=A[i]<=n)表示第i个人的位置。
输出描述:
每组数据输出一行,表示所需要的最少时间。
示例1
输入
5 3 1 4 5 3 2 1 3
输出
1 1
说明
第一组数据选择5为集合地点,第二组数据选择2为集合地点。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[1003]; 5 6 int main(){ 7 int n,m; 8 while(~scanf("%d%d",&n,&m)){ 9 memset(a,0,sizeof(a)); 10 int x; 11 for(int i=1;i<=m;i++) { 12 scanf("%d",&a[i]); 13 } 14 int Min=1e9+7,sum=0; 15 for(int i=1;i<=n;i++){ 16 sum=0; 17 for(int j=1;j<=m;j++){ 18 x=abs(a[j]-i); 19 sum=max(sum,min(x,n-x)); 20 } 21 Min=min(Min,sum); 22 } 23 printf("%d\n",Min); 24 } 25 return 0; 26 }
B 日历中的数字
时间限制:1秒 空间限制:131072K
题目描述
ElemenT马上就要毕业了,他打开日历看了看时间。发现日历上的日期都是2017-04-04这样的格式的,月和日如果不足2位数,前面都会补充0。
给定一个年份和月份,ElemenT把那个月的日期都按上述格式写到纸上,他现在想知道某种数字出现了多少次。
输入描述:
多组输入 每组输入一行,有3个数字y,m,x(1000<=y<=3000,1<=m<=12,0<=x<=9),分别代表年份,月份,和他想知道哪个数字出现的次数。
输出描述:
每组输出一个整数,表示数字x在这个月的日期里出现了多少次。
示例1
输入
2017 4 4 2000 1 0
输出
33 我也不知道,2333
说明
第一组样例中,日中有数字4的为2017-04-04,2017-04-14,2017-04-24,4月一共有30天,因为月份中有4,所以数字4一共出现了30 + 3 = 33次
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 5 int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 6 int b[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; 7 8 int main(){ 9 int y,m,d; 10 while(~scanf("%d%d%d",&y,&m,&d)){ 11 int xx,yy; 12 int sum=0; 13 if(m==2){ 14 if((y%4==0&&y%100!=0)||y%400==0){ 15 xx=29; 16 } 17 else xx=28; 18 } 19 else xx=a[m]; 20 for(int i=1;i<=xx;i++){ 21 int x=i; 22 while(x){ 23 yy=x%10; 24 if(yy==d) sum++; 25 x/=10; 26 } 27 } 28 int mm=m; 29 if(d==0) sum+=9; 30 if(d==0&&m<=9) sum+=xx; 31 while(m){ 32 yy=m%10; 33 if(yy==d) sum+=xx; 34 m/=10; 35 } 36 while(y){ 37 yy=y%10; 38 if(yy==d) sum+=xx; 39 y/=10; 40 } 41 printf("%d\n",sum); 42 } 43 }
C安卓图案解锁
时间限制:1秒 空间限制:131072K
题目描述
栗主席(lizi)是某xxxx大学的一个不得了的程序猿,然而没想到吧,他竟然有女盆友,我们假设为QAQ!!!
那天,QAQ问栗子:你的小米5s的图像解锁密码到底是多少?
栗子:嘛?我仔细想想...
QAQ:你仿佛在逗我...
...
栗子:我的图像解锁用过好多次密码,后来都是用指纹解锁,所以忘记密码辣。但是我记得可能是那几个密码
QAQ:那你务必告诉我...
栗子: ...
然后,栗子就写下了一堆可能的密码,安卓图案解锁中,数字对应的位置已经标出。
但是栗子当然不想把真正的密码告诉QAQ,所以给QAQ的一系列的密码中,甚至有一些密码,是不符合安卓图案解锁的规则的。
QAQ也知道栗子肯定不老实,给了很多错的密码,甚至不符合规则的密码,所以想请你来找出,哪些密码是不符合规则的。
安卓图案解锁的密码有这样的一些特点:
1.每个数字最多只会被使用一次。
2.如果想直接连接两个数字,但是线段中会经过另一个数字,当且仅有那个数字已经在之前就被使用过了,才会合法。(比如你想从1直接连接到9,那么要么是1->3->9,要么是3在之前已经被使用过了,然后才能直接从1->9)
输入描述:
多组输入 每组输入占一行,包含一串数字(1~9),长度不超过30
输出描述:
输出这个安卓图案解锁是否合法,如果合法输出"YES",反之输出"NO" (请参照样例输出,不要输出引号)
示例1
输入
14569 1953 15963 15953
输出
YES NO YES NO
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[10][10]; 5 6 void init(){ 7 a[1][3]=1;a[1][7]=1; 8 a[7][9]=1;a[3][9]=1; 9 a[1][9]=1;a[3][7]=1; 10 a[4][6]=1;a[2][8]=1; 11 } 12 int b[10]; 13 int main(){ 14 string s; 15 16 while(cin>>s){ 17 memset(b,0,sizeof(b)); 18 memset(a,0,sizeof(a)); 19 init(); 20 b[s[0]-'0']=1; 21 int tt=0; 22 for(int i=1;i<s.size();i++){ 23 if(b[s[i]-'0']) { 24 tt=1;break; 25 } 26 b[s[i]-'0']=1; 27 int x=s[i-1]-'0',y=s[i]-'0'; 28 if(x>y) swap(x,y); 29 if(a[x][y]) { 30 tt=1;break; 31 } 32 if(x==4||y==4) 33 a[1][7]=0; 34 if(x==8||y==8) 35 a[7][9]=0; 36 if(x==6||y==6) 37 a[3][9]=0; 38 if(x==2||y==2) 39 a[1][3]=0; 40 if(x==5||y==5){ 41 a[1][9]=0; 42 a[3][7]=0; 43 a[4][6]=0; 44 a[2][8]=0; 45 } 46 } 47 if(tt) printf("NO\n"); 48 else printf("YES\n"); 49 } 50 }
D 小M和天平
时间限制:2秒 空间限制:131072K
题目描述
小M想知道某件物品的重量,但是摆在他面前的只有一个天平(没有游标)和一堆石子,石子可以放左边也可以放右边。他现在知道每个石子的重量。问能不能根据上述条件,能不能测出所问的重量。
输入描述:
多组数据,第一行一个数N,表示石子个数。(1<=N<=100) 接下来第二行N个数,表示石子的重量。(1<=Wi<=100) 接下来第三行一个数M,表示询问个数。(1<=M<=1000) 接下来M行每行一个数k(1<=k<=1e9),表示一个询问。
输出描述:
对于每组数据,输出"YES"或者"NO"
示例1
输入
2 1 4 3 2 4 5
输出
NO YES YES
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[103]; 5 int b[10004]; 6 vector<int > c; 7 8 int main(){ 9 int n; 10 while(~scanf("%d",&n)){ 11 int x; 12 memset(b,0,sizeof(b)); 13 c.clear(); 14 c.push_back(0); 15 for(int i=1;i<=n;i++){ 16 scanf("%d",&x); 17 int l=c.size(); 18 for(int j=0;j<l;j++){ 19 int xx=x+c[j]; 20 if(b[xx]==0){ 21 c.push_back(xx);b[xx]=1; 22 } 23 xx=abs(x-c[j]); 24 if(b[xx]==0){ 25 c.push_back(xx);b[xx]=1; 26 } 27 } 28 } 29 int m; 30 scanf("%d",&m); 31 while(m--){ 32 scanf("%d",&x); 33 if(x<=10000&&b[x]) printf("YES\n"); 34 else printf("NO\n"); 35 } 36 } 37 }
I 主持人的烦恼
时间限制:1秒 空间限制:131072K
题目描述
一天zzq主持一项游戏,共n位同学,需要两两同学为一组来上台来玩一项游戏。
但是,众所周知,玩游戏的时候,如果两个人的颜值差距>=m,就会互相嫌弃。
所以,为了游戏能够好玩。在游戏开始前,zzq已经调查了所有n个同学的颜值。
但是现在问题又来了,zzq想知道,最多能凑出多少组同学一起上台?
需注意一人只能出现在一个组中。
输入描述:
多组输入 第一行两个正整数n m(n<=1e5,m<=1e9),意义见描述 第二行有n个由空格分开的正整数xi(xi<=1e9),第i个同学的颜值
输出描述:
每一行输出一个数,表示最多能凑出多少组。
示例1
输入
4 3 1 3 3 2 4 2 1 4 6 2
输出
2 1
说明
第二组样例中,编号为1的同学(颜值是1)与编号为4的同学(颜值是2),颜值差距为1,可以组成一组
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[100005]; 5 6 int main(){ 7 int n,m; 8 while(~scanf("%d%d",&n,&m)){ 9 for(int i=1;i<=n;i++) 10 scanf("%d",&a[i]); 11 sort(a+1,a+1+n); 12 int sum=0; 13 for(int i=2;i<=n;i++){ 14 if(a[i]-a[i-1]<m) sum++,i++; 15 } 16 printf("%d\n",sum); 17 } 18 }
J 武藏牛奶促销
时间限制:1秒 空间限制:131072K
题目描述
武藏牌牛奶为了吸引顾客,推出优惠活动,可以使用x个空的瓶身,**或者**y个瓶盖,去商店换一瓶全新的武藏牌牛奶。注意,一瓶牛奶包含了瓶身和瓶盖。
现在小萌老师有a个空的瓶身和b个瓶盖,她想喝到尽可能多的牛奶,你知道她到底能喝到多少瓶完整的牛奶吗?
输入描述:
多组输入 每组数据第一行包含4个正整数x y a b(1<=x,y,a,b<=100),意义见题目描述。
输出描述:
对于每组数据,输出一行,表示小萌老师最多能喝多少瓶完整的牛奶。如果能喝无数瓶,输出"INF"(不要输出引号)。
示例1
输入
1 3 1 1 4 3 6 4
输出
INF 4
说明
对于第二组测试样例,小萌老师有6个空的瓶身和4个瓶盖,她用4个瓶身和3个瓶盖换了2瓶牛奶并喝完,此时她就有4个空的瓶身和3个瓶盖。之后她再换2瓶牛奶并喝完,此时只有2个空的瓶身和2个瓶盖,就无法继续兑换了,所以答案是4
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int s[303][303]; 5 int main(){ 6 int x,y,a,b; 7 while(~scanf("%d%d%d%d",&x,&y,&a,&b)){ 8 memset(s,0,sizeof(s)); 9 if(x==1||y==1){ 10 if(a>=1||b>=1) printf("INF\n");continue; 11 } 12 int sum=0; 13 s[a][b]=1; 14 int tt=0; 15 16 while(a>=x||b>=y){ 17 while(a>=x) { 18 sum+=a/x; 19 b+=a/x; 20 a=a+a/x-(a/x)*x; 21 if(s[a][b]==1){ 22 tt=1;break ; 23 } 24 s[a][b]=1; 25 } 26 while(b>=y) { 27 sum+=b/y; 28 a+=b/y; 29 b=b+b/y-(b/y)*y; 30 if(s[a][b]==1){ 31 tt=1;break ; 32 } 33 s[a][b]=1; 34 } 35 if(tt) break; 36 } 37 if(!tt) 38 printf("%d\n",sum); 39 else printf("INF\n"); 40 } 41 } 42 /* 43 2 2 100 100 44 */
L 选择困难症
时间限制:3秒 空间限制:131072K
题目描述
小L有严重的选择困难症。
早上起床后,需要花很长时间决定今天穿什么出门。
假设一共有k类物品需要搭配选择,每类物品的个数为Ai,每个物品有一个喜欢值Vj,代表小L对这件物品的喜欢程度。
小L想知道,有多少种方案,使得选出来的总喜欢值>M
需要注意,每类物品,至多选择1件,可以不选。
输入描述:
多组输入 每组数据第一行输入k M(k<=6,1<=M<=1e8),表示有多少类物品 接下来k行,每行以Ai(1<=Ai<=100)开头,表示这类物品有多少个,接下来Ai个数,第j个为Vj(1<=Vj<=1e8),表示小L对这类物品的第j个的喜欢值是多少。
输出描述:
每组输出一行,表示方案数
示例1
输入
2 5 3 1 3 4 2 2 3 2 1 2 2 2 2 2 2
输出
3 8
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e6+40000; 5 6 int a[N],b[N]; 7 int c[7][200]; 8 9 int main(){ 10 int n,m; 11 while(~scanf("%d%d",&n,&m)){ 12 for(int i=1;i<=n;i++){ 13 scanf("%d",&c[i][0]); 14 for(int j=1;j<=c[i][0];j++) 15 scanf("%d",&c[i][j]); 16 } 17 int l=0; 18 for(int i=1;i<=c[1][0];i++) a[++l]=c[1][i]; 19 for(int i=2;i<=n/2;i++){ 20 int ll=l; 21 for(int j=1;j<=c[i][0];j++){ 22 a[++l]=c[i][j]; 23 for(int k=1;k<=ll;k++) 24 a[++l]=c[i][j]+a[k]; 25 } 26 } 27 int r=0; 28 for(int i=1;i<=c[n/2+1][0];i++) b[++r]=c[n/2+1][i]; 29 for(int i=n/2+2;i<=n;i++){ 30 int rr=r; 31 for(int j=1;j<=c[i][0];j++){ 32 b[++r]=c[i][j]; 33 for(int k=1;k<=rr;k++) 34 b[++r]=c[i][j]+b[k]; 35 } 36 } 37 //for(int i=1;i<=l;i++) cout<<a[i]<<" ";cout<<endl; 38 // for(int i=1;i<=r;i++) cout<<b[i]<<" ";cout<<endl; 39 sort(a+1,a+1+l); 40 ll sum=upper_bound(a+1,a+1+l,m)-a; 41 if(sum>l) sum=0; 42 else sum=l-sum+1; 43 for(int i=1;i<=r;i++){ 44 int xx=m-b[i]; 45 int k=upper_bound(a+1,a+1+l,xx)-a; 46 if(k<=l) 47 sum+=l-k+1; 48 if(b[i]>m) sum++; 49 } 50 cout<<sum<<endl; 51 } 52 }