HDU 5754 Life Winner Bo
四种棋子实质上都是一样的思路:
如果某位置的棋子,它下一步可以走到的位置中 能找到有后手胜的位置,那么该位置先手必胜。
如果某位置的棋子,它下一步可以走到的位置中 全是先手胜,那么该位置后手必胜。
其余三种都用如上思路打表即可,但要注意马的情况(因为马可能有些位置走不到终点):
如果该位置走过去的两个位置都是平局的,那么该位置也是平局。
如果该位置走过去的两个位置都是先手胜,那么该位置后手胜。
如果该位置走过去的两个位置中有至少一个位置是后手胜,那么该位置先手胜。
其余情况,均为平局。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } inline int read() { char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x; } const int maxn=1010; int king[maxn][maxn],rook[maxn][maxn],knight[maxn][maxn],queen[maxn][maxn]; bool r[maxn],c[maxn],x[2*maxn]; int check(int a,int b) { if(a<=0||a>1000) return -1; if(b<=0||b>1000) return -1; return knight[a][b]; } void init() { memset(king,-1,sizeof king); memset(rook,-1,sizeof rook); memset(knight,-1,sizeof knight); memset(queen,-1,sizeof queen); king[1][1]=0; for(int i=2;i<=1000;i++) king[1][i]=king[i][1]=king[i-1][1]^1; for(int i=2;i<=1000;i++) for(int j=2;j<=1000;j++) if(king[i][j-1]==0||king[i-1][j]==0||king[i-1][j-1]==0) king[i][j]=1; else king[i][j]=0; memset(r,0,sizeof r); memset(c,0,sizeof c); rook[1][1]=0; r[1]=1; c[1]=1; for(int i=2;i<=1000;i++) rook[i][1]=rook[1][i]=1; for(int i=2;i<=1000;i++) for(int j=2;j<=1000;j++) if(r[i]==1||c[j]==1) rook[i][j]=1; else rook[i][j]=0, r[i]=1, c[j]=1; knight[1][1]=0; for(int i=2;i<=1000;i++) for(int j=2;j<=1000;j++) { if(check(i-2,j-1)==-1&&check(i-1,j-2)==-1) continue; if(check(i-2,j-1)==1&&check(i-1,j-2)==1) {knight[i][j]=0; continue;} if(check(i-2,j-1)==0||check(i-1,j-2)==0) {knight[i][j]=1; continue;} else continue; } memset(r,0,sizeof r); memset(c,0,sizeof c); memset(x,0,sizeof x); queen[1][1]=0; r[1]=1; c[1]=1; x[1]=1; for(int i=2;i<=1000;i++) queen[i][1]=queen[1][i]=1; for(int i=2;i<=1000;i++) for(int j=2;j<=1000;j++) { int num; if(i-min(i-1,j-1)==1) num=j-min(i-1,j-1); else num=999+i-min(i-1,j-1); if(r[i]==1||c[j]==1||x[num]==1) queen[i][j]=1; else queen[i][j]=0, r[i]=1, c[j]=1, x[num]=1; } } int main() { init(); int T; scanf("%d",&T); while(T--) { int n,m,type,ans; scanf("%d%d%d",&type,&n,&m); if(type==1) ans=king[n][m]; if(type==2) ans=rook[n][m]; if(type==3) ans=knight[n][m]; if(type==4) ans=queen[n][m]; if(ans==0) printf("G"); else if(ans==1) printf("B"); else printf("D"); printf("\n"); } return 0; }