题目:
题解:
基本上算是抄的黄学长的qwq
http://hzwer.com/848.html
黄学长的bfs写的炒鸡棒
tips:
不要过分依赖于stl里的queue,有的时候手打队列更方便。
把重复部分写成函数调用。
为什么棋盘hash不需要考虑当前走到那个颜色???
hzwer学长好像是没有考虑
我觉得要考虑吖
codevs数据太水,也看不出对错来23333333333
代码:
不考虑颜色
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=1005000;
const int mod=9875321;
bool hve[10000050];
char q[inf][5][5];
char a[5][5];
int dx[]={0,0,1,0,-1},dy[]={0,1,0,-1,0};
int stp[inf],lst[inf];
int ans=-1,head,tail;
bool can(int pos,int x,int y){
if(x<=0||x>4||y<=0||y>4) return 0;
if(q[pos][x][y]=='B'&&lst[pos]==0) return 0;
if(q[pos][x][y]=='W'&&lst[pos]==1) return 0;
return 1;
}
int gethash(char a[5][5]){
int key=0;
int t=0;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(a[i][j]=='B') t=0;
if(a[i][j]=='W') t=1;
if(a[i][j]=='O') t=2;
key=(key*3+t)%mod;
}
}
return key;
}
bool same(char a,char b,char c,char d){
if((a==b)&&(b==c)&&(c==d)) return 1;
return 0;
}
bool ys(char a[5][5]){
for(int i=1;i<=4;i++){
if(same(a[i][1],a[i][2],a[i][3],a[i][4])) return 1;
if(same(a[1][i],a[2][i],a[3][i],a[4][i])) return 1;
}
if(same(a[1][1],a[2][2],a[3][3],a[4][4])) return 1;
if(same(a[1][4],a[2][3],a[3][2],a[4][1])) return 1;
return 0;
}
void move(int pos,int x,int y){
for(int i=1;i<=4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(!can(pos,xx,yy)) continue;//边界,黑白,
for(int s=1;s<=4;s++){
for(int t=1;t<=4;t++)
a[s][t]=q[pos][s][t];
}
a[x][y]=q[pos][xx][yy];
a[xx][yy]='O';
int hsh=gethash(a);//判重
if(hve[hsh]) continue;
hve[hsh]=1;
if(ys(a)) {
ans=stp[pos]+1;
return ;
}
tail++;
for(int s=1;s<=4;s++){
for(int t=1;t<=4;t++)
q[tail][s][t]=a[s][t];
}
lst[tail]=(lst[pos]^1);
stp[tail]=stp[pos]+1;
}
return ;
}
void bfs(){
head=0;tail=1;
while(head<=tail){
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(q[head][i][j]=='O') move(head,i,j);
}
}
if(ans!=-1) return ;
head++;
}
}
int main(){
for(int i=1;i<=4;i++){
cin>>a[i]+1;
for(int j=1;j<=4;j++){
q[1][i][j]=q[0][i][j]=a[i][j];
}
}
int hsh=gethash(a);
hve[hsh]=1;
lst[0]=0;lst[1]=1;
stp[0]=0;stp[1]=0;
bfs();
printf("%d\n",ans);
/* for(int i=0;i<=tail;i++){
for(int s=1;s<=4;s++){
for(int t=1;t<=4;t++) printf("%c",q[i][s][t]);
printf("\n");
}
printf(" %d \n",stp[i]);
}*/
return 0;
}
考虑颜色
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=1005000;
const int mod=9875321;
bool hve[10000050];
char q[inf][5][5];
char a[5][5];
int dx[]={0,0,1,0,-1},dy[]={0,1,0,-1,0};
int stp[inf],lst[inf];
int ans=-1,head,tail;
bool can(int pos,int x,int y){
if(x<=0||x>4||y<=0||y>4) return 0;
if(q[pos][x][y]=='B'&&lst[pos]==0) return 0;
if(q[pos][x][y]=='W'&&lst[pos]==1) return 0;
return 1;
}
int gethash(int last,char a[5][5]){//考虑颜色
int key=last;
int t=0;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(a[i][j]=='B') t=0;
if(a[i][j]=='W') t=1;
if(a[i][j]=='O') t=2;
key=(key*3+t)%mod;
}
}
return key;
}
bool same(char a,char b,char c,char d){
if((a==b)&&(b==c)&&(c==d)) return 1;
return 0;
}
bool ys(char a[5][5]){
for(int i=1;i<=4;i++){
if(same(a[i][1],a[i][2],a[i][3],a[i][4])) return 1;
if(same(a[1][i],a[2][i],a[3][i],a[4][i])) return 1;
}
if(same(a[1][1],a[2][2],a[3][3],a[4][4])) return 1;
if(same(a[1][4],a[2][3],a[3][2],a[4][1])) return 1;
return 0;
}
void move(int pos,int x,int y){
for(int i=1;i<=4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(!can(pos,xx,yy)) continue;//边界,黑白,
for(int s=1;s<=4;s++){
for(int t=1;t<=4;t++)
a[s][t]=q[pos][s][t];
}
a[x][y]=q[pos][xx][yy];
a[xx][yy]='O';
int hsh=gethash(lst[pos],a);//判重
if(hve[hsh]) continue;
hve[hsh]=1;
if(ys(a)) {
ans=stp[pos]+1;
return ;
}
tail++;
for(int s=1;s<=4;s++){
for(int t=1;t<=4;t++)
q[tail][s][t]=a[s][t];
}
lst[tail]=(lst[pos]^1);
stp[tail]=stp[pos]+1;
}
return ;
}
void bfs(){
head=0;tail=1;
while(head<=tail){
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(q[head][i][j]=='O') move(head,i,j);
}
}
if(ans!=-1) return ;
head++;
}
}
int main(){
for(int i=1;i<=4;i++){
cin>>a[i]+1;
for(int j=1;j<=4;j++){
q[1][i][j]=q[0][i][j]=a[i][j];
}
}
int hsh=gethash(1,a);
hve[hsh]=1;
hsh=gethash(0,a);
hve[hsh]=1;
lst[0]=0;lst[1]=1;
stp[0]=0;stp[1]=0;
bfs();
printf("%d\n",ans);
/* for(int i=0;i<=tail;i++){
for(int s=1;s<=4;s++){
for(int t=1;t<=4;t++) printf("%c",q[i][s][t]);
printf("\n");
}
printf(" %d \n",stp[i]);
}*/
return 0;
}