codeforces C. Permutation Game(博弈)
阿新 • • 發佈:2018-12-21
題目大意:有n個位置,每個位置有一個值a[i]。兩個人輪流玩遊戲。移動小球,小球假如當前在i位置,規則:找到一個位置j滿足a[j]>a[i]且abs(j-i)%a[i]=0,這樣就可以把球從i位置放到j位置。是不能移動小球的為loser。求當球初始位置在1~n時的輸贏結果。
由於
a. 對於必勝態,一定有一個後繼狀態是必敗的。
b. 對於必敗態,所有後繼都是必勝的。
沒有後繼為必敗態
如3後繼是1和2。其中1是必敗態,2是必勝態。因為存在一個後繼是必敗態所以3為必勝態。
本題確定每個點的狀態
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int a[maxn]; int num[maxn]; int f[maxn]; int q[maxn]; vector<int >vt[maxn]; int main() { int n; while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { for(int j=i+a[i];j<=n;j+=a[i]) { if(a[j]>a[i]) { vt[j].push_back(i);///到j的點 num[i]++;///i能到達的地方個數 } } } for(int i=1;i<=n;i++) { for(int j=i-a[i];j>=1;j-=a[i]) { if(a[j]>a[i]) { vt[j].push_back(i);///到j的點 num[i]++;///i能到達的地方de個數 } } } memset(f,-1,sizeof(f)); int r=1;int l=1; for(int i=1;i<=n;i++) { if(!num[i]) { f[i]=0; q[r++]=i; } } while(l<r) { int u=q[l++]; for(int i=0;i<vt[u].size();i++) { int v=vt[u][i]; if(f[v]==-1)///v點還沒確定,根據後繼u確定v的必態 { if(f[u]==0) f[v]=1; else f[v]=0; } else///v之前已經確定過狀態,就是v後繼出現必敗態,v就是必勝態 { if(f[u]==0) f[v]=1; } num[v]--; if(!num[v]) q[r++]=v; } } for(int i=1;i<=n;i++) { if(f[i]) printf("A"); else printf("B"); } printf("\n"); } }