PKU演習問メモ(10/25)
No. | 問題名 | 問題の種類および解法 | 難易度 |
---|---|---|---|
1166 | The Clocks | 幅優先探索 | ★★☆☆☆ |
1166 The Clocks
問題概要
状態が0→1→2→3→0→……と変わるダイアルが9つあり、それぞれの名前をABCDEFGHIとする。
これらについて、
- ABDE
- ABC
- BCEF
- ADG
- BDEFH
- CFI
- DEGH
- GHI
- EFHI
の9通りのうちいずれかの組のダイアルを同時に1回だけ回す操作ができる。
全てのダイアルを0にするための手順のうち最小回数のものを一つ出力せよ。
ソースコード
なんかセンスのないコードになってしまった。
char *g[]={"ABDE","ABC","BCEF","ADG","BDEFH","CFI","DEGH","GHI","EFHI"}; int gain[9][9]; int move[330000]; int toi(int *a) { int n=0; rep(i,9)n<<=2,n+=a[i]; return n; } void toa(int *a,int n) { rep(i,9)a[8-i]=n&3,n>>=2; } int main() { rep(i,9)for(int j=0;g[i][j];j++)gain[i][g[i][j]-'A']=1; int st[9]={0}; rep(i,9)scanf("%d",st+i); int si=toi(st); rep(i,330000)move[i]=-1; queue<int> Q; Q.push(si); while(!Q.empty()) { int s=Q.front(); Q.pop(); if(s==0)break; rep(i,9) { int a[9]; toa(a,s); rep(j,9)a[j]=a[j]+gain[i][j]&3; int nx=toi(a); if(move[nx]>=0)continue; move[nx]=i; Q.push(nx); } } vi ans; for(int p=0;p!=si;) { ans.pb(move[p]); int a[9]; toa(a,p); rep(i,9)a[i]=a[i]+4-gain[move[p]][i]&3; p=toi(a); } int n=ans.size(); rep(i,n) { if(i)putchar(' '); printf("%d",ans[n-i-1]+1); } puts(""); return 0; }