Problem C

一个字符串A循环移位n种可能性有cnt种和字符串B相等,

那么如果当一个串处于B状态时循环移位n-1种里面有cnt-1种可能到达B,n-cnt种可能到达非B

那么如果当一个串处于非B状态时循环移位n-1种里面有cnt种可能到达B,n-cnt-1种可能到达非B

然后DP就行

#include<cstdio> #include<cstring> typedef __int64 lld; const lld mod = 1000000007; lld dp[100010][2]; char a[2010],b[1010]; int main() { int i,m; gets(a);gets(b); int n=strlen(a); scanf("%d",&m); dp[0][strcmp(a,b)!=0]=1; for(i=0;i<n;i++) a[i+n]=a[i]; lld cnt=0; for(i=0;i<n;i++) if(strncmp(a+i,b,n)==0) cnt++; for(i=0;i<m;i++){ dp[i+1][0]=(dp[i][0]*(cnt-1)+dp[i][1]*cnt)%mod; dp[i+1][1]=(dp[i][0]*(n-cnt)+dp[i][1]*(n-cnt-1))%mod; } printf("%I64d\n",dp[m][0]); return 0; }


 Problem E

#include<cstdio> #include<cstring> #include<math.h> #include<algorithm> using namespace std; int main(){ int a,b,c,d,e,f; scanf("%d %d %d %d %d %d",&e,&f,&a,&b,&c,&d); if(a>c) swap(a,c); if(b>d) swap(b,d); if((d-b)>=5 || (c-a)>=5) printf("Second\n"); else{ if((d-b)==4 && (c-a)==4) printf("Second\n"); else if(max(d-b,c-a)==4 && min(d-b,c-a)==3) printf("Second\n"); else printf("First\n"); } }

E题如果上面的规律找不到就只能借助搜索穷举结果

#include <algorithm> #include <bitset> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <fstream> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; bool board[10][10]; bool table[10][10]; bool go(int xa,int ya,int xb,int yb,int turn){ // go返回值为true时First赢,返回值False时Second赢 if (xa == xb && ya == yb) return true; if (!turn) { if (!board[xa][ya]){ if (xa < xb && go(xa + 1,ya,xb,yb,1)) return true; //First随便走一步go返回true,则First赢 if (ya < yb && go(xa,ya + 1,xb,yb,1)) return true; } if (!board[xb][yb]){ if (xa < xb && go(xa,ya,xb - 1,yb,1)) return true; if (ya < yb && go(xa,ya,xb,yb - 1,1)) return true; } return false; // 上面已经穷举了First的所有走法, } else { for (int i = xa; i <= xb; i++) for (int j = ya; j <= yb; j++) if (!board[i][j]){ if (i == xa && j == ya) continue; if (i == xb && j == yb) continue; board[i][j] = true; int out = go(xa,ya,xb,yb,0); board[i][j] = false; if (!out) return false; //Second随便走一步go返回false,则Second赢 } return go(xa,ya,xb,yb,0); //表示Second标在其他位置 } } bool canwin(int a,int b){ memset(board,false,sizeof(board)); if (a && b){ if (!table[a - 1][b] && !table[a][b - 1]) return table[a][b] = false; } return table[a][b] = go(0,0,a,b,0); } int main() { int tmp; for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++) tmp = canwin(i,j); int n,m,xa,ya,xb,yb; scanf("%d %d %d %d %d %d", &n, &m, &xa, &ya, &xb, &yb); int da = abs(xa - xb),db = abs(ya - yb); if (da >= 10 || db >= 10){ printf("Second\n"); return 0; } if (table[da][db]) printf("First\n"); else printf("Second\n"); }