【codevs1004】四子连棋
今天复习一下bfs,顺便把之前一直没a的四字连棋做了一下
这个题,我认为难点就在于移动棋子的一系列操作,太长了。
ps:不知道为啥,洛谷和codevs同时不待见getchar,在自己从codevs那里拿了了些数据,手动测了一下,发现都对了,好迷
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct in { int a[6][6]; int as,ne; }ter,qaq; int ans,h[4]={-1,0,1,0},z[4]={0,1,0,-1}; bool ha[(100003)<<1]; char s[5]; queue<in>qwq; inline int hash(in x) { int re=1,tot=1; for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) re=re*3+x.a[i][j]; re%=100003; return re; } inline bool cha(int i,int j,int k,int l) { if(i==j&&j==k&&k==l&&l==i) return 1; return 0; } inline bool pan() { for(int i=1;i<=4;i++) { if(cha(qaq.a[i][1],qaq.a[i][2],qaq.a[i][3],qaq.a[i][4])) return 1; if(cha(qaq.a[1][i],qaq.a[2][i],qaq.a[3][i],qaq.a[4][i])) return 1; } if(cha(qaq.a[1][1],qaq.a[2][2],qaq.a[3][3],qaq.a[4][4])) return 1; if(cha(qaq.a[1][4],qaq.a[2][3],qaq.a[3][2],qaq.a[4][1])) return 1; return 0; } inline bool can(int x,int y) { if(x<=0||x>4||y<=0||y>4) return 0; if(qaq.a[x][y]==qaq.ne) return 1; return 0; } inline void move(int x,int y) { for(int i=0;i<4;i++) { int nx=x+h[i],ny=y+z[i]; if(can(nx,ny)) { in owo=qaq; swap(owo.a[x][y],owo.a[nx][ny]); if(!ha[hash(owo)]) { owo.as=qaq.as+1; if(qaq.ne==1) owo.ne=0; if(qaq.ne==0) owo.ne=1; qwq.push(owo); } } } } inline void bfs() { while(!qwq.empty()) { qaq=qwq.front(); if(pan()) { ans=qaq.as; return; } ha[hash(qaq)]=1; qwq.pop(); for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(qaq.a[i][j]==2) move(i,j); } } int main() { for(int i=1;i<=4;i++) { scanf("%s",s+1); for(int j=1;j<=5;j++) { if(s[j]=='B') ter.a[i][j]=0; else if(s[j]=='W') ter.a[i][j]=1; else if(s[j]=='O') ter.a[i][j]=2; } } ter.as=0,ter.ne=0; qwq.push(ter); ter.ne=1; qwq.push(ter); bfs(); if(!ans) ans=1; printf("%d",ans); }