题解:AT_abc380_f [ABC380F] Exchange Game

coding_goat

2024-11-18 08:01:21

Solution

如果有一种操作使得之后的情况都可以转换为我胜,那么这就是我的必胜点,反之就是我的必败点。 注意是**可以**从桌上拿起一张牌,不是必须。 然后就是要记忆化搜索,注意要记录此时是谁操作,因为有可能出现两个人手牌一样但是操作方不一样。 ```cpp #include<bits/stdc++.h> #define mem(a,b) memset((a),(b),sizeof(a)) #define m0(a) memset((a),0,sizeof(a)) #define lb(x) ((x)&-(x)) #define lc(x) ((x)<<1) #define rc(x) (((x)<<1)|1) #define pb(G,x) (G).push_back((x)) #define For(a,b,c) for(int a=(b);a<=(c);a++) #define Rep(a,b,c) for(int a=(b);a>=(c);a--) #define in1(a) a=read() #define in2(a,b) a=read(), b=read() #define in3(a,b,c) a=read(), b=read(), c=read() #define inn(i,n,a) For(i,1,n) a[i]=read(); #define ll long long #define i128 __int128 using namespace std; inline int read() { int xx= 0;int f= 1; char c = getchar(); while(c<'0'||c>'9') { if(c=='-') f= -1; c= getchar(); } while(c>='0'&&c<='9') { xx= (xx<<1)+(xx<<3)+(c^48); c= getchar(); } return xx*f; } #define maxn 15 short f[2][(1<<12)+114][(1<<12)+514]; int a[maxn]; int n,m,l; int out[maxn],top; void put(int x) { m0(out); top=0; while(x) out[++top]=x&1,x>>=1; For(i,1,13) cout<<out[i]; puts(""); } bool dfs(int dep,int s1,int s2) { // cout<<dep<<'\n';put(s1); put(s2); puts("---"); bool res=0; if(f[dep][s1][s2]!=-1) return f[dep][s1][s2]; if(dep&1) { res=0; For(i,0,n+m+l-1) { if(!((s1>>i)&1)) continue; if((s2>>i)&1) continue; For(j,0,n+m+l-1) { if(((s1|s2)>>j)&1) continue; if(a[i+1]>a[j+1]) if(!dfs((dep^1),(s1^(1<<i))|(1<<j),s2)) res=1; } if(!dfs((dep^1),(s1^(1<<i)),s2)) res=1; } } else { res=0; For(i,0,n+m+l-1) { if(!((s2>>i)&1)) continue; if((s1>>i)&1) continue; For(j,0,n+m+l-1) { if(((s1|s2)>>j)&1) continue; if(a[i+1]>a[j+1]) if(!dfs((dep^1),s1,(s2^(1<<i))|(1<<j))) res=1; } if(!dfs((dep^1),s1,(s2^(1<<i)))) res=1; } } f[dep][s1][s2]=res; return res; } signed main() { mem(f,-1); in3(n,m,l); For(i,1,n+m+l) in1(a[i]); cout<<(dfs(1,(1<<(n))-1,(1<<(m+n))-(1<<n))?"Takahashi":"Aoki"); }