結果
| 問題 |
No.936 Are
|
| コンテスト | |
| ユーザー |
otamay6
|
| 提出日時 | 2019-11-29 15:47:13 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 4,243 bytes |
| コンパイル時間 | 2,192 ms |
| コンパイル使用メモリ | 177,744 KB |
| 実行使用メモリ | 6,824 KB |
| 最終ジャッジ日時 | 2024-11-21 00:25:21 |
| 合計ジャッジ時間 | 4,673 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 2 WA * 23 |
ソースコード
#include<bits/stdc++.h>
#include<fstream>
#define REP(i,n) for(int i=0,i##_len=(n);i<i##_len;++i)
#define rep(i,a,b) for(int i=int(a);i<int(b);++i)
#define All(x) (x).begin(),(x).end()
using namespace std;
using ll = long long;
const ll mod=1e9+7;
int N,K;
int L1,R1,L2,R2;
//頂点k=l1+5r1+25l2+125r2+i
//i君の手番で、0(lot)君の手がl1,r1、1君の手がl2,r2
ll from[1250]={},to[1250]={};
vector<vector<int>> graph(1250);
vector<bool> banned(1250,false);//高橋君が頂点kの状況に行くか行かないか
void init(){
cin>>N>>K;
cin>>L1>>R1>>L2>>R2;
from[L1+5*R1+25*L2+125*R2+625*N]=1;
}
void make_graph(){
//lot君の勝ちに行く頂点を禁止する
REP(i,5) REP(j,5){
if(i==0&&j==0) continue;
int pre=(5-i)%5;
banned[i+5*j+25*pre]=true;
banned[i+5*j+125*pre]=true;
pre=(5-j)%5;
banned[i+5*j+25*pre]=true;
banned[i+5*j+125*pre]=true;
}
//高橋君の勝ちに行く頂点に辺を張る
REP(i,5) REP(j,5){
int v=25*i+125*j;
int pre=(5-i)%5;
graph[pre+25*i+125*j+625].push_back(v);
graph[5*pre+25*i+125*j+625].push_back(v);
pre=(5-j)%5;
graph[pre+25*i+125*j+625].push_back(v);
graph[5*pre+25*i+125*j+625].push_back(v);
}
//全ての頂点から高橋君が次のターンで負けるような辺以外すべてを伸ばす
REP(u,1250) if(graph[u].empty()){
int X[5]={};
int now=u;
REP(i,5){
X[i]=now%5;
now/=5;
}
if((X[0]==0&&X[1]==0)||(X[2]==0&&X[3]==0)) continue;
if(X[4]==0){//lot君のターン
REP(i,2){
if(X[i]==0) continue;
graph[u].push_back(X[0] + 5*X[1] + 25*((X[2]+X[i])%5) + 125*X[3] + 625 );
graph[u].push_back(X[0] + 5*X[1] + 25*X[2] + 125*((X[3]+X[i])%5) + 625 );
}
REP(l,5){
int r=X[0]+X[1]-l;
if(r<0) break;
r%=5;
if(l==0&&r==0) continue;
if((r==X[0]&&l==X[1])||(l==X[0]&&r==X[1])) continue;
graph[u].push_back(l+5*r+25*X[2]+125*X[3]+625);
}
}
else{//高橋君のターン
rep(i,2,4){
if(X[i]==0) continue;
int v = (X[0]+X[i])%5 + 5*X[1] + 25*X[2] + 125*X[3];
if(!banned[v]) graph[u].push_back(v);
v = X[0] + 5*((X[1]+X[i])%5) + 25*X[2] + 125*X[3];
if(!banned[v]) graph[u].push_back(v);
}
REP(l,5){
int r=X[2]+X[3]-l;
if(r<0) break;
r%=5;
if(l==0&&r==0) continue;
if((r==X[2]&&l==X[3])||(l==X[2]&&r==X[3])) continue;
int v = X[0] + 5*X[1] + 25*l + 125*r;
if(!banned[v]) graph[u].push_back(v);
}
}
}
//負け確なところは何も繋がれてないので全部繋ぐ
rep(u,625,1250) if(graph[u].empty()){
int X[5]={};
int now=u;
REP(i,5){
X[i]=now%5;
now/=5;
}
if((X[0]==0&&X[1]==0)||(X[2]==0&&X[3]==0)) continue;
rep(i,2,4){
if(X[i]==0) continue;
int v = (X[0]+X[i])%5 + 5*X[1] + 25*X[2] + 125*X[3];
graph[u].push_back(v);
v = X[0] + 5*((X[1]+X[i])%5) + 25*X[2] + 125*X[3];
graph[u].push_back(v);
}
REP(l,5){
int r=X[2]+X[3]-l;
if(r<0) break;
r%=5;
if(l==0&&r==0) continue;
if((r==X[2]&&l==X[3])||(l==X[2]&&r==X[3])) continue;
int v=X[0]+5*X[1]+25*l+125*r;
graph[u].push_back(v);
}
}
}
int main(){
init();
make_graph();
ll ans=0;
REP(i,K) {
REP(l1,5) REP(r1,5) REP(l2,5) REP(r2,5){
int u=l1+5*r1+25*l2+125*r2+625*N;
for(auto v:graph[u]){
to[v]+=from[u];
to[v]%=mod;
}
}
REP(i,5) REP(j,5){
ans+=to[i+5*j+625];
ans%=mod;
}
REP(j,1250) from[j]=0;
N=1-N;
swap(from,to);
}
cout<<ans<<endl;
}
otamay6