問題はこちら
No.103 素因数ゲーム リターンズ - yukicoder
このゲームが本質的には山崩し(Nim)と同じであることはyukicoder No.2 素因数ゲーム - メモで説明した
前回との違いは、割れる回数が2回までになっていることのみ
よって(N言っちゃだめゲームと同様に考えて)各山はmod3で値を見れば良いことが分かる(厳密には、これが各山のgrundy数になっていることから分かる)
ということで前回のコードを流用して
int main(){ int s,t,n,m,i; scanf("%d",&n); s=0; while(n--){ scanf("%d",&m); for(i=2;i<=m;i++){ for(t=0;m%i==0;){ m/=i; t++; } s^=t%3; } } puts(s?"Alice":"Bob"); return 0; }
同じく前回のコードを流用することで
i,t,s; main(m){ for(gets(&i);~scanf("%d",&m);)for(i=2;m%i?s^=t%3,t=0,m>++i:(m/=i,++t);); s=!puts(s?"Alice":"Bob"); }
ここまでは自明に短縮できる
あとは頑張ってループ圧縮
for(gets(&i);~scanf("%d",&m);)for(i=2;m%i?s^=t%3,t=0,m>++i:(m/=i,++t);); //↓形式的圧縮 for(gets(&i);m%i?s^=t%3,t=0,m>++i?:(i=2,~scanf("%d",&m)):(m/=i,++t);); //最初はi>48,m=1なので、「i=2,~scanf("%d",&m)」の部分が実行される for(gets(&i);m%i?s^=t%3,t=0,++i>m?i=2,~scanf("%d",&m):1:(m/=i,++t);); //カッコを外す for(gets(&i);m%i?s^=t%3,t=0,++i>m?i=-~scanf("%d",&m):1:(m/=i,++t);); //scanfの返り値を使う
ということで
i,t,s; main(m){ for(gets(&i);m%i?s^=t%3,t=0,++i>m?i=-~scanf("%d",&m):1:(m/=i,++t);); s=!puts(s?"Alice":"Bob"); }
108B