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");
}