题目:(luogu翻译错的很多)
Alice和Bob玩游戏,每人有8张牌,牌的值为0~4。每一轮当前玩家选择自己的牌A和对手的牌B,然后将A的值变为( A + B )%5,其中A和B都不是0。
当一个人手牌全为0时他就赢了。
T(T<=1e5)组询问,求最后谁赢了,如果都没赢输出Deal。(两个人都是最优方案)
题解:
博弈搜索。
只不过本题有无解情况,因此dfs会卡(应该是我太弱了)。所以考虑用bfs,相当于dfs中直接回溯。
代码:
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int num[10][10][10][10],cnt; int T; int dp[250000],ind[250000];//first:second void init() { for(int a=0;a<=8;a++) for(int b=0;a+b<=8;b++) for(int c=0;a+b+c<=8;c++) for(int d=0;a+b+c+d<=8;d++) num[a][b][c][d]=++cnt; } int tn(int a,int b) { return (a-1)*cnt+b-1; } int cg(int a[5],int b[5]) { return tn(num[a[1]][a[2]][a[3]][a[4]],num[b[1]][b[2]][b[3]][b[4]]); } int gt(int a[5]) { int ret = 0; for(int i=1;i<=4;i++)ret+=(a[i]!=0); return ret; } struct node { int a[5],b[5]; int aa(){return num[a[1]][a[2]][a[3]][a[4]];} int bb(){return num[b[1]][b[2]][b[3]][b[4]];} int cc(){return tn(aa(),bb());} node df() { node ret; for(int i=0;i<=4;i++)ret.a[i]=b[i],ret.b[i]=a[i]; return ret; } }tmp; queue<node>q; int a0[5],b0[5]; void dfsb(int dep,int sum) { if(dep==5) { int c = cg(a0,b0),ga=gt(a0),gb=gt(b0); ind[c] = ga*gb; if(!(ga*gb)) { if(!ga)dp[c]=1; else dp[c]=2; tmp.a[0]=8-a0[1]-a0[2]-a0[3]-a0[4],tmp.a[1]=a0[1],tmp.a[2]=a0[2],tmp.a[3]=a0[3],tmp.a[4]=a0[4]; tmp.b[0]=8-b0[1]-b0[2]-b0[3]-b0[4],tmp.b[1]=b0[1],tmp.b[2]=b0[2],tmp.b[3]=b0[3],tmp.b[4]=b0[4]; q.push(tmp); } return ; } for(b0[dep]=0;b0[dep]+sum<=8;b0[dep]++) dfsb(dep+1,sum+b0[dep]); } void dfsa(int dep,int sum) { if(dep==5){dfsb(1,0);return ;} for(a0[dep]=0;a0[dep]+sum<=8;a0[dep]++) dfsa(dep+1,sum+a0[dep]); } void bfs() { while(!q.empty()) { tmp = q.front(); q.pop(); node v = tmp.df(); for(int j=1;j<=4;j++) { if(!v.b[j])continue; for(int i=0;i<=4;i++) { if(!v.a[i]||(i-j+5)%5==0)continue; v.a[i]--; v.a[(i-j+5)%5]++; int c = v.cc(),c0 = tmp.cc(); if(!ind[c]) { v.a[i]++; v.a[(i-j+5)%5]--; continue; } if(dp[c0]==2) { dp[c]=1; ind[c]=0; q.push(v); v.a[i]++; v.a[(i-j+5)%5]--; continue; }else if(!dp[c0]) { dp[c]=3; } ind[c]--; v.a[i]++; v.a[(i-j+5)%5]--; if(ind[c])continue; if(!dp[c])dp[c]=2; else dp[c]=0; v.a[i]--; v.a[(i-j+5)%5]++; q.push(v); v.a[i]++; v.a[(i-j+5)%5]--; } } } } int typ; int main() { init(); dfsa(1,0); bfs(); scanf("%d",&T); while(T--) { memset(a0,0,sizeof(a0)); memset(b0,0,sizeof(b0)); scanf("%d",&typ); for(int x,i=1;i<=8;i++) { scanf("%d",&x); a0[x]++; } for(int x,i=1;i<=8;i++) { scanf("%d",&x); b0[x]++; } int c = typ?cg(b0,a0):cg(a0,b0); int ans = dp[c]; if(!ans) { printf("Deal "); }else { if((ans-1)^typ) { printf("Bob "); }else { printf("Alice "); } } } return 0; }