A题 :(字符串查找,水题)
题意 :输入字符串,如果字符串中包含“ Apple”, “iPhone”, “iPod”, “iPad” 就输出 “MAI MAI MAI!”,如果出现 “Sony” 就输出“SONY DAFA IS GOOD!” ,大小写敏感。
思路 : 字符串查找,水题。
1 #include <string.h> 2 #include <stdio.h> 3 #include <iostream> 4 5 using namespace std ; 6 7 char str[20000]; 8 9 int main() 10 { 11 int i; 12 while(gets(str)) 13 { 14 int len=strlen(str); 15 for(i=0; i<len; i++) 16 { 17 if(str[i]=='A' && str[i+1]=='p' && str[i+2]=='p' && str[i+3]=='l' && str[i+4]=='e') 18 printf("MAI MAI MAI!\n"); 19 if(str[i]=='i' && str[i+1]=='P' && str[i+2]=='h' && str[i+3]=='o' && str[i+4]=='n'&&str[i+5] == 'e') 20 printf("MAI MAI MAI!\n"); 21 if(str[i]=='i' && str[i+1]=='P' && str[i+2]=='a' && str[i+3]=='d') 22 printf("MAI MAI MAI!\n"); 23 if(str[i]=='i' && str[i+1]=='P' && str[i+2]=='o' && str[i+3]=='d') 24 printf("MAI MAI MAI!\n"); 25 if(str[i]=='S' && str[i+1]=='o' && str[i+2]=='n' && str[i+3]=='y') 26 printf("SONY DAFA IS GOOD!\n"); 27 } 28 } 29 return 0; 30 }
E题 :(博弈)
题意 : n堆珠子,两个人轮流玩儿,每一次,玩家从某一堆中拿出一些扔掉,至少拿出一个,然后对这堆剩下的,玩家可以不再操作,或者可以将剩下的分为两堆,但是每堆至少一个,然后下一个玩家玩儿,如果哪个玩家玩完一把之后没有珠子了。谁就胜了。
思路 : 类似于Nim游戏,就是多了一个分堆的问题,其实无大碍。。。还是那样分。。。。
#include <stdio.h> #include <string.h> #include <iostream> using namespace std ; int main() { int n ; while(scanf("%d",&n)!=EOF) { int a,sum = 0 ; for(int i = 0 ; i < n ;i++) { scanf("%d",&a) ; sum ^= a ; } if(sum)puts("Win") ; else puts("Lose") ; } return 0 ; }
F题 :(BFS)
题意 : 告诉你一个骰子上下左右前后上的数字分别是多少,问转最少多少次能够转到另一个骰子的状态,如果不能输出-1,有前转后转左转右转。
思路 : 记录下当前状态在四种转向方式之后变成什么状态,然后加入队列,看能否转到终态。
#include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std ; int mul[7] = {1,10,100,1000,10000,100000}; struct node { int sta,step ; friend bool operator < (node a,node b) { return a.step > b.step ; } } p,temp1,temp2; int state,a[7] ; bool vis[700000] ; int BFS() { priority_queue<node>Q ; Q.push(p) ; vis[p.sta] = true ; while(!Q.empty()) { temp1 = Q.top() ; Q.pop() ; if(temp1.sta == state) return temp1.step ; int ss = temp1.sta ; for(int i = 0 ; i < 6 ; i++) { a[i] = ss % 10 ; ss /= 10 ; } //左转 p.sta = 0 ; p.step = temp1.step + 1 ; p.sta = 1*a[3]+10*a[2]+100*a[0]+1000*a[1]+10000*a[4]+100000*a[5] ; if(!vis[p.sta]) { Q.push(p) ; vis[p.sta] = true ; } //右转 p.sta = 0 ; p.step = temp1.step + 1 ; p.sta = 1*a[2]+10*a[3]+100*a[1]+1000*a[0]+10000*a[4]+100000*a[5] ; if(!vis[p.sta]) { Q.push(p) ; vis[p.sta] = true ; } //后转 p.sta = 0 ; p.step = temp1.step + 1 ; p.sta = 1*a[4]+10*a[5]+100*a[2]+1000*a[3]+10000*a[1]+100000*a[0] ; if(!vis[p.sta]) { Q.push(p) ; vis[p.sta] = true ; } //前转 p.sta = 0 ; p.step = temp1.step + 1 ; p.sta = 1*a[5]+10*a[4]+100*a[2]+1000*a[3]+10000*a[0]+100000*a[1] ; if(!vis[p.sta]) { Q.push(p) ; vis[p.sta] = true ; } } return -1 ; } int main() { int a; while(scanf("%d",&a)!=EOF) { p.sta = a ; for(int i = 1 ; i < 6 ; i++) { scanf("%d",&a) ; p.sta += a*mul[i] ; } p.step = 0 ; state = 0 ; for(int i = 0 ; i < 6 ; i++) { scanf("%d",&a) ; state += a*mul[i] ; } //printf("%d %d\n",p.sta,state) ; memset(vis,false,sizeof(vis)) ; if(p.sta == state) { puts("0") ; continue ; } int t = BFS() ; printf("%d\n",t) ; } return 0 ; }
H题 : (位运算)
题意 : 有n+1个数,数组a满足两个条件,是数组里的所有数大小都在[0,n]之间,而且两两不相等,b数组也满足这个条件,然后让你求t = (a0 ⊕ b0) + (a1 ⊕ b1) +···+ (an ⊕ bn)这个t的最大值,然后输出当t最大的时候b数组的数分别是什么。
思路 : 给你一个数,你所能异或到的最大数就是全都是1,例如5(101)能够异或到的最大数就是111,是跟010异或之后,for循环倒着找每个数跟全都是1的情况下得到的数是多少即可。a^b=c,则a^c=b,b^c=a。。。。。。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 5 using namespace std; 6 7 int a[101011],b[101011],vis[101011]; 8 9 int sum(int x)//求这个数有多少位 10 { 11 int cnt = 0 ; 12 while(x) 13 { 14 x >>= 1 ; 15 cnt ++ ; 16 } 17 return cnt ; 18 } 19 int main() 20 { 21 int n ; 22 while(scanf("%d",&n)!= EOF) 23 { 24 memset(vis,0,sizeof(vis)) ; 25 for(int i = 0 ; i <= n ; i++) 26 { 27 scanf("%d",&a[i]) ; 28 } 29 for(int i = n ; i >= 0 ; i--) 30 { 31 if(vis[i]) continue ; 32 int ss = (1 << sum(i)) -1 ;//求出这个数全是1 33 int temp = ss ^ i ; 34 b[temp] = i ; 35 b[i] = temp ; 36 vis[temp] = vis[i] = 1 ; 37 } 38 long long s = 0 ; 39 for(int i = 0 ; i <= n ; i++) 40 s += (long long)(b[i] ^ i) ; 41 printf("%I64d\n",s) ; 42 for(int i = 0 ; i <= n ; i++) 43 printf(i == n ? "%d\n":"%d ",b[a[i]]) ; 44 } 45 return 0 ; 46 }
I题:(矩阵快速幂)
题意 : 一个矩阵,告诉你第0行是233 2333 23333 233333……然后给出第0列,让你自己构造矩阵,a[i][j]=a[i-1][j]+a[i][j-1],然后问你a[n][m]等于多少。
思路 : 首先构造矩阵,本题中列号与行号都是从1开始。把0所在的位置换成23,假定给定的样例是:3 7 24 47 16 ,现在的第一列就应该是23 24 47 16。由此,第二列第个数233就是由10个23加1个3组成的,再根据a[i][j]=a[i-1][j]+a[i][j-1],就可以通过前一列来推出后一列了。将3作为最后一个数。
23 233
24 233+24
47 233+24 +47
16 233+24 +47+16
3 3
由以上可知,将第一列横置得,23 24 47 16 3,接下来可以递推下一列了
233 = 10*23+0*24+0*47+0*16+1*3
233+24 = 10*23+1*24+0*47+0*16+1*3
233+24 +47 = 10*23+1*24+1*47+0*16+1*3
233+24 +47+16 = 10*23+1*24+1*47+1*16+1*3
3 = 0*23+0*24+0*47+0*16+1*3
将系数画成一个矩阵 10 0 0 0 1
10 1 0 0 1
10 1 1 0 1
10 1 1 1 1
0 0 0 0 1
所以,可以得出规律
a[0][m] | 10 0 0 0 1| | a[0][m-1] |
a[1][m] | 10 1 0 0 1| | a[1][m-1] |
a[2][m] = | 10 1 1 0 1| * | a[2][m-1] |
a[3][m] | 10 1 1 1 1| | a[3][m-1] |
3 | 0 0 0 0 1| | 3 |
所以a[n][m]就等于中间那个矩阵的m-1次方乘上第一列。。。。。。
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <iostream> 5 #define LL __int64 6 #define mod 10000007 7 using namespace std ; 8 int n,m ; 9 struct mat 10 { 11 LL v[15][15] ; 12 mat() 13 { 14 memset(v,0,sizeof(v)) ; 15 for(int i = 1 ; i <= n+2 ; i++) 16 v[i][i] = 1 ; 17 } 18 }; 19 mat e ; 20 21 mat matrix_mul(mat p1,mat p2) 22 { 23 mat t ; 24 for(int i = 1 ; i <= n+2 ; i++) 25 { 26 for(int j = 1 ; j <= n+2 ; j++) 27 { 28 t.v[i][j] = 0 ; 29 for(int k = 1 ; k <= n+2 ; k++) 30 { 31 t.v[i][j] = (t.v[i][j] + (p1.v[i][k]*p2.v[k][j])%mod)%mod ; 32 } 33 } 34 } 35 return t ; 36 } 37 mat matrix_mi(mat p,int k) 38 { 39 mat t ; 40 // for(int i = 1 ; i <= n+2 ; i ++) 41 // t.v[i][i] = 1 ; 42 while(k) 43 { 44 if(k&1) 45 { 46 t = matrix_mul(t,p) ; 47 } 48 k >>= 1 ; 49 p = matrix_mul(p,p) ; 50 } 51 return t ; 52 } 53 void Init() 54 { 55 memset(e.v,0,sizeof(e.v)) ; 56 for(int i = 1 ; i <= n+1 ; i++) 57 e.v[i][1] = 10 ; 58 for(int i = 2 ; i <= n+1 ; i++) 59 { 60 for(int j = 2 ; j <= n+1 ; j++) 61 { 62 if(i >= j) 63 e.v[i][j] = 1 ; 64 } 65 } 66 for(int i = 1 ; i <= n+2 ; i++) 67 e.v[i][n+2] = 1 ; 68 } 69 int main() 70 { 71 LL a[1000],sum[1000] ; 72 while(~scanf("%d %d",&n,&m)) 73 { 74 sum[0] = 0 ; 75 for(int i = 1 ; i <= n ; i++) 76 { 77 scanf("%I64d",&a[i]) ; 78 sum[i] = sum[i-1]+a[i] ; 79 } 80 Init() ; 81 mat ans = matrix_mi(e,m-1) ; 82 mat cnt ; 83 cnt.v[1][1] = 233 ; 84 for(int i = 2 ; i <= n+1 ; i++) 85 cnt.v[i][1] = (233 + sum[i-1])%mod ; 86 cnt.v[n+2][1] = 3 ; 87 ans = matrix_mul(ans,cnt) ; 88 printf("%I64d\n",ans.v[n+1][1]%mod) ; 89 } 90 return 0 ; 91 }