标签:oca msu cas print make names sid comm swap
题意:
4种棋。
棋子首先在(1,1),你要移动到(n,m);
谁先移动到终点谁就赢了,注意骑士可能走向平局
题解:
首先国王可以预处理答案
皇后是威佐夫博弈
车是个典型的nim博弈
骑士呢,你注意到有个平局,就是说,如果当前走下一个状态的时候,面临了必败和平局的情况,你是要走平局的,这个点注意一下就能AC了
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double Pi = acos(-1.0); const int N = 3e3+100, M = 2e5+20, mod = 1e9+7, inf = 2e9; int h[5],gw[N][N],qs[N][N]; void init() { gw[0][0] = 0; for(int i = 0; i <= 1000; ++i) { for(int j = 0; j <= 1000; ++j) { memset(h,0,sizeof(h)); if(i>=1)h[gw[i-1][j]] = 1; if(j>=1)h[gw[i][j-1]] = 1; if(i>=1&&j>=1) h[gw[i-1][j-1]] = 1; if(h[0]) gw[i][j]=1; else gw[i][j] = 0; } } memset(qs,-1,sizeof(qs)); qs[0][0] = 0;int cnt = 0; for(int i = 0; i <= 1000; ++i) { for(int j = 0; j <= 1000; ++j) { int ok = 0; memset(h,0,sizeof(h)); if(i>=2&&j>=1&&qs[i-2][j-1]!=-1&&qs[i-2][j-1]<=4)h[qs[i-2][j-1]] = 1,ok = 1; if(j>=2&&i>=1&&qs[i-1][j-2]!=-1&&qs[i-1][j-2]<=4)h[qs[i-1][j-2]] = 1,ok++; if(i == 0 && j == 0) continue; if(ok) { if(h[0]) qs[i][j] = 1; else if(!h[0] && ok < 2) qs[i][j] = -1; else qs[i][j] = 0; } else qs[i][j] = -1; } } // cout<<cnt<<endl; // cout<<qs[1][2]<<endl; } int main() { int T;init(); scanf("%d",&T); while(T--) { int type,n,m; scanf("%d%d%d",&type,&n,&m); n--,m--; if(type == 1) {//国王 if(gw[n][m])printf("B\n"); else printf("G\n"); } else if(type == 2) {//车 if((n ^ m) != 0)printf("B\n"); else printf("G\n"); } else if(type == 3) {//马 if(qs[n][m]==-1) printf("D\n"); else if(qs[n][m]) printf("B\n"); else printf("G\n"); } else {//皇后 if(n > m) swap(n,m); double k = (sqrt(5)-1.0)/2.0; int j = n * k; if(n != (int) (j*(1+k))) j++; if(n + j == m) printf("G\n"); else printf("B\n"); } } return 0; }
标签:oca msu cas print make names sid comm swap
原文地址:http://www.cnblogs.com/zxhl/p/6013567.html