最終問の割にコードは短い。
https://codeforces.com/contest/1536/problem/F
問題
N個のマスが円周状に並んでいる。
これを用いて2人でターン制のゲームを行う。
自ターンでは、空きマスを1つ選び、AかBの文字を埋める。
ただし、同じ文字が2つ並ぶ埋め方をしてはならない。
ゲームの展開は何通りあるか。
解法
もしN個中M個のマスが埋まった状態で終わったとする。
- N=Mの場合、ABABAB....と埋まるので順番を無視すると2通り。順番がN!通りなので、解は2*N!通り。
- M<Nの場合、まず2M≧Nである必要がある。この時、ABABAB...の各文字の間に、空きますが0個か1個入った状態である。
- なので、1番目のマスが空いているケースと開いていないケースを考えると、2*M!*(Binom(M,N-M)+Binom(M-1,N-M-1))通り。
int N; const ll mo=1000000007; const int NUM_=1400001; static ll fact[NUM_+1],factr[NUM_+1],inv[NUM_+1]; ll comb(ll N_, ll C_) { if(C_<0 || C_>N_) return 0; return factr[C_]*fact[N_]%mo*factr[N_-C_]%mo; } void solve() { int i,j,k,l,r,x,y; string s; inv[1]=fact[0]=factr[0]=1; for (int i=2;i<=NUM_;++i) inv[i] = inv[mo % i] * (mo - mo / i) % mo; for (int i=1;i<=NUM_;++i) fact[i]=fact[i-1]*i%mo, factr[i]=factr[i-1]*inv[i]%mo; cin>>N; ll ret=0; for(x=0;x<=N;x+=2) { if(x*2<N) continue; if(x==N) { ret+=2*fact[N]; } else { ret+=2*fact[x]*(comb(x,N-x)+comb(x-1,N-x-1))%mo; } } cout<<ret%mo<<endl; }
まとめ
この回全体的に簡単だったっぽい?