周赛题解
问题 A: 一道签到题
时间限制: 2 Sec 内存限制: 128 MB提交: 62 解决: 27
[提交][状态][讨论版]
题目描述
我想说这是一道签到题,意思就是本次测试中最水的一道,不过我这样说你真的愿意相信我吗?哈哈,题目是这样的给你一下小数,然后请告诉我分别告诉我这个小数的循环节的循环次数、循环节以及循环节长度
输入
输入包括多组测试数据每组测试数据1行,包括一个小数,小数的长度不超过200,小数大于0小于100
输出
分别输出这个小数的循环节的长度、循环节以及循环次数,中间以一个空格间隔
样例输入
8.6987698769876987 0.666 5.1
样例输出
4 6987 4 1 6 3 1 1 1代码:
题解:kmp;
1 #include<stdio.h> 2 #include<string.h> 3 char m[210],s[210]; 4 int p[210],len; 5 void fn(){ 6 int i=0,j=-1; 7 p[0]=-1; 8 while(i<len){ 9 if(j==-1||s[i]==s[j]){ 10 i++;j++; 11 p[i]=j; 12 } 13 else j=p[j]; 14 } 15 } 16 int main(){ 17 while(~scanf("%s",m)){ 18 int i=0,j,k; 19 while(m[i]!='.')i++; 20 for(j=i+1,k=0;m[j];j++,k++){ 21 s[k]=m[j]; 22 } 23 s[k]='\0'; 24 //printf("%s\n",s); 25 len=strlen(s); 26 fn(); 27 //for(i=0;i<len;i++)printf("%d ",p[i]);puts(""); 28 printf("%d ",len-p[len]); 29 for(j=p[len];j<len;j++)printf("%c",s[j]); 30 printf(" %d\n",len/(len-p[len])); 31 } 32 return 0; 33 }
问题 B: MZY寻宝
时间限制: 1 Sec 内存限制: 128 MB提交: 157 解决: 49
[提交][状态][讨论版]
题目描述
贪心的MZY去一个迷宫寻宝。已知:若MZY在位置(x, y),他下一次只能移动到(x-1, y)、(x+1, y)、(x, y-1)、(x, y+1)四个位置中的任一个(前提不能越界)。
毕竟他不是我,我可以直接飞到宝物那里去。由于MZY比较笨拙,他移动一步需要1分钟。请你帮他算出找到宝物所需要花费的最少时间。
迷宫是一个N*M的地图,图中只有四个数字。
0:此处是空的,可以走
1:此处有障碍,不可以走
2:MZY起点
3:宝物位置(只有一个宝物)
题目保证CZY至少有一条路可以到达宝物位置。
输入
输入数据有多组。
每组以两个整数N和M开始,分别表示迷宫的行数和列数,接下来N行每行有M个数。(1 <= N, M <= 10)
输出
输出MZY找到宝物的最少需要花费的时间。(以秒为单位)
样例输入
2 2 0 2 1 3
样例输出
60
题解:错了12次终于交对了,尝试了各种方法,刚开始广搜,wa然后再用深搜还是wa换了种深搜写法不用数组了,然后就一直运行错误,跟魔王那题一样老是运行错误
都无奈了,然后又用广搜,换了种写法,用优先队列重新写也不管超内存了,然后就过了。。。曲折淋漓啊; dfs代码:
1 #include<stdio.h> 2 #define MIN(x,y) x<y?x:y 3 int map[15][15]; 4 int nx,ny,minstep,N,M,sx,sy; 5 void dfs(int x,int y,int step){ 6 if(x<0||y<0||x>=N||y>=M||map[x][y]==1)return; 7 if(step>minstep)return; 8 if(map[x][y]==3){ 9 minstep=MIN(minstep,step); 10 return; 11 } 12 map[x][y]==1; 13 dfs(x+1,y,step+1); 14 dfs(x-1,y,step+1); 15 dfs(x,y+1,step+1); 16 dfs(x+1,y-1,step+1); 17 map[x][y]=0; 18 return; 19 } 20 int main(){ 21 while(~scanf("%d%d",&N,&M)){minstep=0xfffffff; 22 for(int i=0;i<N;i++){ 23 for(int j=0;j<M;j++){ 24 scanf("%d",&map[i][j]); 25 if(map[i][j]==2)sx=i,sy=j; 26 } 27 } 28 dfs(sx,sy,0); 29 printf("%d\n",minstep*60); 30 } 31 return 0; 32 }
bfs代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 struct Node{ 6 int nx,ny; 7 int step; 8 friend bool operator < (Node a,Node b){ 9 return a.step>b.step; 10 } 11 }; 12 Node a,b; 13 int map[11][11],N,M; 14 int visit[11][11]; 15 int disx[4]={0,0,1,-1}; 16 int disy[4]={1,-1,0,0}; 17 int st,sx,sy,flot; 18 void bfs(){int t; 19 priority_queue<Node>dl; 20 a.nx=sx;a.ny=sy;a.step=0; 21 dl.push(a); 22 visit[sx][sy]=1; 23 while(!dl.empty()){ 24 a=dl.top(); 25 dl.pop(); 26 if(map[a.nx][a.ny]==3){ 27 st=a.step; 28 return; 29 } 30 visit[a.nx][a.ny]=1; 31 for(int i=0;i<4;i++){ 32 b.nx=a.nx+disx[i];b.ny=a.ny+disy[i];b.step=a.step+1; 33 if(b.nx<0||b.ny<0||b.nx>=N||b.ny>=M||visit[b.nx][b.ny])continue; 34 if(map[b.nx][b.ny]==1)continue; 35 if(map[b.nx][b.ny]==0||map[b.nx][b.ny]==3){ 36 dl.push(b); 37 } 38 } 39 } 40 } 41 int main(){int x,y; 42 while(~scanf("%d%d",&N,&M)){st=0; 43 memset(map,0,sizeof(map)); 44 memset(visit,0,sizeof(visit)); 45 for(x=0;x<N;x++)for(y=0;y<M;y++){ 46 scanf("%d",&map[x][y]); 47 if(map[x][y]==2)sx=x,sy=y; 48 } 49 bfs(); 50 printf("%d\n",st*60); 51 } 52 return 0; 53 }
问题 C: CZY的组合数烦恼
时间限制: 3 Sec 内存限制: 128 MB提交: 46 解决: 21
[提交][状态][讨论版]
题目描述
czy最近对组合数产生了浓厚的兴趣,一天他心血来潮,想排n个数字,但是很快他发现种类太多了,于是他决定从中随机找出m个数排,但还是太多了,所以他想请聪明的你写个程序帮助他找到所有种类的排列
输入
输入包括多组测试数据,每组包括一行整数n(1<=n<10),m(1<=m<=n),空格间隔
输出
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。
样例输入
5 3
样例输出
543 542 541 532 531 521 432 431 421 321
题解:不多说南阳组合数;
1 #include<stdio.h> 2 #include<string.h> 3 int n,m; 4 int num[10]; 5 void dfs(int top,int tot){ 6 if(tot>=m){ 7 for(int i=0;i<m;i++)printf("%d",num[i]); 8 puts(""); 9 return; 10 } 11 for(int i=top;i>0;i--){ 12 num[tot]=i; 13 dfs(i-1,tot+1); 14 } 15 return ; 16 } 17 int main(){ 18 while(~scanf("%d%d",&n,&m)){ 19 dfs(n,0); 20 } 21 return 0; 22 }
问题 E: 陈公公找女友
时间限制: 1 Sec 内存限制: 128 MB提交: 44 解决: 17
[提交][状态][讨论版]
题目描述
话说CZY来到了HPU之后,每天对着电脑码代码,码了一学期了,陈公公有一天敲代码敲累了,此刻的陈公公是身心疲惫啊,他突然想:要是有一个Girlfriend多好?于是,陈公公想要在学校找一个Girlfriend。话说在男女比7:1的比例之下很难找到意中人,是不是?可惜这难不倒我们“英(jing)姿(li)飒(feng)爽(fu)”的陈公公,找女友要先买礼物对吧。对于陈公公这种“壕”,当然要买高端大气上档次的啦!陈公公要斥巨资买条钻石手链,送给他心仪已久的女生(从此,陈公公又多了个外号“钻石陈”)。我们都知道手链五颜六色的很吸引人。陈公公也知道女生喜欢颜色比较多的手链,但是手链又不能毫无规律的颜色多而已。我们要买的手链必须是颜色够多,还要有规律,什么叫做有规律?就是有循环的。假如给定参照手链“RGB”,再给一个手链比如“RGBRGBRGB”它包含了3个参照手链。陈公公称包含值为:美丽度。因为包含3个参考串,所以这个手链美丽度就为3.
陈公公想要买一个美丽度大于1的手链,但是又不能只有一种颜色,怎么挑一个最好的呢?这个问题有点难想,并且可惜陈公公对颜色的分辨能力不够高(轻微色盲),不能很好的判断买哪一条手链,要不是陈公公自己都能编程解决这个问题了。陈公公很无奈啊,他想到了有爱心的协会成员,希望求助协会成员,请你帮他选一个最美的手链。这关乎到陈公公能否追到心意的女孩啊!人生大事啊!陈公公说了,能帮他解决这个问题的童鞋,他就会请你吃饭!PS:帮陈公公解决这个问题的人,记得找陈公公请客。
输入
有多组测试数据,输入先给出参考手链(参考手链长度大于1),然后输入一个T(0<T<20),代表陈公公选的T组数据。每组数据第一行是参照手链,第二行是陈公公想知道美丽度的手链(长度不小于参考手链)。由于陈公公比较壕,所以他选的手链的珠子最多可以达到100000。
输出
输出数据也有T行,每行输出,最大美丽度,和相应的手链。如果美丽度相同就输出手链最长的,看下面测试样例。
样例输入
RGB 4 RGBRGB RGBRGBRGB RGBWRGBWRGBW RGRGBRGGRBG RWW 3 RWWWWR RWWWWRW RWRWRW WWR 5 WWRWW WWWRWWRWR WWWWWWWW WRWRWRWR WRRWRWRWWW
样例输出
3 RGBWRGBWRGBW 1 RWWWWRW 2 WWWRWWRWR
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 struct Node{ 6 char a[100010]; 7 int buty; 8 int len; 9 }; 10 Node da[25]; 11 int cmp(Node a,Node b){ 12 if(a.buty!=b.buty)return a.buty>b.buty; 13 else return a.len>b.len; 14 } 15 int p[100010],flot; 16 char b[100010]; 17 void fp(){ 18 int i=0,j=-1; 19 p[0]=-1; 20 while(b[i]){ 21 if(j==-1||b[i]==b[j]){ 22 i++;j++; 23 p[i]=j; 24 } 25 else j=p[j]; 26 } 27 } 28 void kmp(char *a,int x){ 29 fp(); 30 int j=0; 31 while(a[x]){ 32 if(j==-1||a[x]==b[j]){ 33 x++;j++; 34 if(!b[j]){flot++; 35 kmp(a,x); 36 return; 37 } 38 } 39 else j=p[j]; 40 } 41 } 42 int main(){ 43 int T; 44 while(~scanf("%s",b)){ 45 memset(da,0,sizeof(da)); 46 memset(p,0,sizeof(p)); 47 scanf("%d",&T); 48 for(int i=0;i<T;i++){ 49 scanf("%s",da[i].a); 50 da[i].len=strlen(da[i].a); 51 flot=0; 52 kmp(da[i].a,0); 53 da[i].buty=flot; 54 } 55 sort(da,da+T,cmp); 56 printf("%d %s\n",da[0].buty,da[0].a); 57 } 58 return 0; 59 }
问题 G: 打败魔王
时间限制: 2 Sec 内存限制: 128 MB提交: 43 解决: 6
[提交][状态][讨论版]
题目描述
可怜的公主又被魔王抓走了。魔王这次准备在T时刻与公主成亲,不过公主深信智勇的骑士CZY肯定能将她救出。
已知:公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。
CZY一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那CZY就会被撞死。
CZY在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。
输入
输入有多组测试数据。
每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N*M(1 <= N,M <=10)。T如上所意。
接下去的前N*M表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。
输出
如果CZY能够在T时刻能找到公主就输出“YES”,否则输出“NO”。
样例输入
1 4 2 .#.# *.#P
样例输出
NO
题解:比赛的时候最后看dfs实在不行就敲了广搜,敲完时间也到了,不知道对不,应该问题不大,两个代码贴上;
dfs:
1 #include<stdio.h> 2 #define MIN(x,y) x<y?x:y 3 const int INF=0xfffffff; 4 char map[2][12][12]; 5 int nx,ny,nz,mt,N,M,flot,T; 6 char p; 7 void dfs(int x,int y,int z,int t){ 8 if(x<0||y<0||x>=N||y>=M||map[z][x][y]=='*')return; 9 if(map[z][x][y]=='P'){ 10 if(t<=T)flot=1; 11 return; 12 } 13 if(flot)return ; 14 if(map[z][x][y]=='#')dfs(x,y,1-z,t); 15 map[z][x][y]='*'; 16 dfs(x+1,y,z,t+1); 17 dfs(x-1,y,z,t+1); 18 dfs(x,y+1,z,t+1); 19 dfs(x,y-1,z,t+1); 20 map[z][x][y]='.'; 21 return; 22 } 23 int main(){ 24 while(~scanf("%d%d%d",&N,&M,&T)){ 25 flot=0; 26 for(int x=0;x<N;x++)scanf("%s",map[0][x]); 27 for(int x=0;x<N;x++)scanf("%s",map[1][x]); 28 //printf("%s %s\n",map[0][0],map[1][0]); 29 dfs(0,0,0,0); 30 if(flot)puts("YES"); 31 else puts("NO"); 32 } 33 return 0; 34 }
bfs:
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 struct Node{ 6 int nx,ny,nz; 7 int step; 8 friend bool operator < (Node a,Node b){ 9 return a.step>b.step; 10 } 11 }; 12 Node a,b; 13 char map[2][11][11]; 14 int visit[2][11][11]; 15 int disx[4]={0,0,1,-1}; 16 int disy[4]={1,-1,0,0}; 17 int st,sx,sy,flot,N,M,T; 18 void bfs(){int t; 19 priority_queue<Node>dl; 20 a.nx=0;a.ny=0;a.step=0;a.nz=0; 21 dl.push(a); 22 visit[0][sx][sy]=1; 23 while(!dl.empty()){ 24 a=dl.top(); 25 dl.pop(); 26 if(map[a.nz][a.nx][a.ny]=='P'){ 27 if(a.step<=T)flot=1; 28 //printf("%d\n",a.step); 29 return; 30 } 31 visit[a.nz][a.nx][a.ny]=1; 32 for(int i=0;i<4;i++){ 33 b.nx=a.nx+disx[i];b.ny=a.ny+disy[i];b.step=a.step+1;b.nz=a.nz; 34 if(b.nx<0||b.ny<0||b.nx>=N||b.ny>=M||visit[b.nz][b.nx][b.ny])continue; 35 if(map[b.nz][b.nx][b.ny]=='*')continue; 36 if(map[b.nz][b.nx][b.ny]=='#')b.step=a.step+1,b.nz=1-b.nz,dl.push(b); 37 else if(map[b.nz][b.nx][b.ny]=='.'||map[b.nz][b.nx][b.ny]=='P'){ 38 dl.push(b); 39 } 40 } 41 } 42 } 43 int main(){int x,y; 44 while(~scanf("%d%d%d",&N,&M,&T)){flot=0; 45 memset(map,0,sizeof(map)); 46 memset(visit,0,sizeof(visit)); 47 for(x=0;x<N;x++)scanf("%s",map[0][x]); 48 for(x=0;x<N;x++)scanf("%s",map[1][x]); 49 bfs(); 50 if(flot)puts("YES"); 51 else puts("NO"); 52 } 53 return 0; 54 }
问题 H: CZY的工程
时间限制: 1 Sec 内存限制: 128 MB提交: 68 解决: 36
[提交][状态][讨论版]
题目描述
CZY总是遇到这样或那样的问题,现在他又遇到了一个,CZY接到一个大的工程,想想这是走上人生巅峰的第一步啊,CZY想想就高兴,可是这个工程太大了,他需要很多人的帮助才可以,但是为了方便工作,CZY希望他的团队两人两人之间都是朋友关系,或者间接是朋友关系。毕竟是大油水的工程啊,来了一群小伙伴报名,CYZ想请聪明的你帮忙算一算,他可以招到的最大的人数是多少
输入
输入包含多组测试数据,每组测试数据第一行一个n,表示来报名的小伙伴们的编号1-100,后边接n行,每行两个整数a b,表示编号a和b的小伙伴是朋友关系
输出
输出包括一行,即CZY可以招到的最大的人数是多少
样例输入
4 1 2 3 4 5 6 1 6
样例输出
4
题解:基础并查集,记录节点数;
代码:
1 #include<stdio.h> 2 #define MAX(x,y) x>y?x:y 3 const int INF=-0xfffffff; 4 int pre[120]; 5 int py[120]; 6 int max; 7 int find(int x){ 8 if(x==pre[x])return x; 9 else return pre[x]=find(pre[x]); 10 } 11 void initial(){ 12 for(int i=1;i<=100;i++)pre[i]=i,py[i]=1; 13 } 14 void merge(int x,int y){ 15 int f1,f2; 16 f1=find(x);f2=find(y); 17 if(f1!=f2){ 18 pre[f1]=f2; 19 py[f2]+=py[f1]; 20 max=MAX(max,py[f2]); 21 } 22 } 23 int main(){ 24 int N,a,b; 25 while(~scanf("%d",&N)){ 26 max=INF; 27 initial(); 28 while(N--){ 29 scanf("%d%d",&a,&b); 30 merge(a,b); 31 } 32 printf("%d\n",max); 33 } 34 return 0; 35 }
问题 I: CZY找句子
时间限制: 1 Sec 内存限制: 128 MB提交: 85 解决: 38
[提交][状态][讨论版]
题目描述
YY喜欢读书,而且总是喜欢从书上摘取好的句子或词语,但是抄完之后她变忘了在哪,于是她就请CZY帮她,CZY感觉这我多我可咋找啊!
于是又来麻烦聪明的你,为了方便CZY早已用高端译码机器把句子变成的数字,他想让你告诉他句子在文章中出现的位置。(位置从1开始)
输入
输入包括多组测试数据,每组测试数据包含三行,第一行包含两个整数n(1<=n<=1000000),m(1<=m<=1000),分别代表文章的长度,和所摘取的句子的长度,
第二行包含n个整数表示文章,第三行包括m各整数表示句子
输出
输出所摘取的句子在文章中的位置
样例输入
13 5 1 2 1 2 3 1 2 3 1 3 2 1 2 1 2 3 1 3
样例输出
6
题解:kmp模板: 代码:
1 #include<stdio.h> 2 #include<string.h> 3 int a[1000010],b[1010]; 4 int p[1010],n,m; 5 void getp(){ 6 int i=0,j=-1; 7 p[0]=-1; 8 while(i<m){ 9 if(j==-1||b[i]==b[j]){ 10 i++;j++; 11 p[i]=j; 12 } 13 else j=p[j]; 14 } 15 } 16 int kmp(){ 17 getp(); 18 int i=0,j=0; 19 // printf("%d\n",n); 20 while(i<n){ 21 if(j==-1||a[i]==b[j]){ 22 i++;j++; 23 if(j>=m)return i-j+1; 24 } 25 else j=p[j]; 26 } 27 } 28 int main(){ 29 int t; 30 while(~scanf("%d%d",&n,&m)){ 31 memset(p,0,sizeof(p)); 32 for(int i=0;i<n;i++)scanf("%d",&a[i]); 33 for(int i=0;i<m;i++)scanf("%d",&b[i]); 34 t=kmp(); 35 //for(int i=0;i<m;i++)printf("%d ",p[i]);puts(""); 36 printf("%d\n",t); 37 } 38 return 0; 39 }
问题 F: CZY的YY难题
时间限制: 1 Sec 内存限制: 128 MB提交: 6 解决: 1
[提交][状态][讨论版]
题目描述
CZY终于又和萌妹子的关系又进了一步,终于知道了妹子的名字,原来她叫YY,CZY跟着那个女孩也学到了很多的数学知识,CZY感觉自己快要超神了,于是嘚瑟起来,YY对此不屑一顾,冷笑一声“呵呵”后,便给CZY出了一道数学题,YY给了CZY一个数n,又给了m个数,让他从中找一些数,让这些数的和等于n,并让他把所有的情况写出来。这下可把CZY给打击到了,于是他又来请教聪明的你,请你帮帮他
输入
题目包含多组测试数据,每组测试数据包含两行,第一行包含两个整数n,m(1<=n,m<1000)
第二行包含m个数
输出
按从大到小的顺序输出所有符合的情况,没有符合的情况就输出NONE
样例输入
4 6 4 3 2 2 1 1 5 3 2 1 1 400 12 50 50 50 50 50 50 25 25 25 25 25 25
样例输出
4 3+1 2+2 2+1+1 NONE 50+50+50+50+50+50+25+25+25+25 50+50+50+50+50+25+25+25+25+25+25跟交换卡片那题有点像,关键在于去冲重,用while去重;
题解:
1 #include<stdio.h> 2 #include<stdlib.h> 3 int me[1010],str[1010]; 4 int m,n,flot; 5 int cmp(const void *a,const void *b){ 6 return (int *)a>(int *)b; 7 } 8 void dfs(int top,int tot,int sum){ 9 if(sum==n){ 10 for(int i=0;i<tot;i++){flot=1; 11 if(i)printf("+"); 12 printf("%d",str[i]); 13 }puts(""); 14 return; 15 } 16 for(int i=top;i<m;i++){ 17 str[tot]=me[i]; 18 dfs(i+1,tot+1,sum+str[tot]); 19 while(me[i]==me[i+1]&&i<m)i++; 20 } 21 return; 22 } 23 int main(){ 24 while(~scanf("%d%d",&n,&m)){flot=0; 25 for(int i=0;i<m;i++)scanf("%d",&me[i]); 26 qsort(me,m,sizeof(me[0]),cmp); 27 dfs(0,0,0); 28 if(!flot)puts("NONE"); 29 } 30 return 0;}
问题 D: CZY追女孩
时间限制: 1 Sec 内存限制: 128 MB提交: 106 解决: 19
[提交][状态][讨论版]
题目描述
CZY遇到了一个萌妹子,他使出浑身解数想要博得她的好感,但是妹子居然是个数学学霸!一天,那个女孩在解数列问题时遇到了一点麻烦,她有数列的前3项,数列不是等比数列就是等差数列,她很想知道这个数列的第n项是什么,但是n可能很大,她算不出来,CZY很想帮她,可是CZY是个学渣,于是想请聪明的你来帮忙求出数列的第n项,由于数据可能太大了,最后的结果对200907取余就好
输入
输入包含多组测试数据,每组测试数据包含4个整数,前三个整数是数列的前三项,最后一个数是n,四个数的范围都是1~10^9
输出
输出这个数列的第n项%200907
样例输入
1 2 3 5 1 2 4 5
样例输出
5 16
题解:
快速幂,同余定理;
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 int quikpow(int x,int y){ 5 int ans=1; 6 while(y){if(y&1)ans*=x; 7 x*=x; 8 x%=200907; 9 y>>=1; 10 } 11 return ans; 12 } 13 int main(){int x,y,z,n,tot,d,an,a1,q,anser; 14 while(~scanf("%d%d%d%d",&x,&y,&z,&n)){ 15 if(x+z==2*y){d=y-x;a1=x;tot=n-1; 16 d%=200907; 17 a1%=200907; 18 tot%=200907; 19 an=a1+tot*d; 20 printf("%d\n",an%200907); 21 } 22 else{ 23 q=y/x; 24 a1=x%200907; 25 anser=a1*quikpow(q,n-1); 26 printf("%d\n",anser%200907); 27 } 28 } 29 return 0; 30 }