bfs版
1000007不是个质数。
Hash的时候需要判一下最后一次下的棋子颜色。(不然过不了样例,虽然能A……)
注意交换顺序。
zz代码↓
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
string a;
int mp[7][7];
struct alice
{
int now[5][5];//目前棋盘
int x1,y1,x2,y2;//空位
int step,color;//这一步下的颜色
int hash;
};
queue<alice>q;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
bool flag=0,vis[10000027];
int ans=0;
int HASH(alice la)
{
int ret=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
{
ret=(ret*3+la.now[i][j])%9999991;
}
return ret*la.color%9999991;
}
bool ok(alice hei)
{
for(int i=1;i<=4;i++)
{
if(hei.now[i][1]==hei.now[i][2]&&hei.now[i][2]==hei.now[i][3]&&hei.now[i][3]==hei.now[i][4]) return true;
if(hei.now[1][i]==hei.now[2][i]&&hei.now[3][i]==hei.now[2][i]&&hei.now[3][i]==hei.now[4][i]) return true;
}
if(hei.now[1][1]==hei.now[2][2]&&hei.now[2][2]==hei.now[3][3]&&hei.now[3][3]==hei.now[4][4]) return true;
if(hei.now[4][1]==hei.now[3][2]&&hei.now[3][2]==hei.now[2][3]&&hei.now[2][3]==hei.now[1][4]) return true;
return false ;
}
void bfs()
{
while(!q.empty())
{
alice ha=q.front();//上一步 (已经下完
if(ok(ha))
{
ans=ha.step;
return;
}
for(int i=0;i<4;i++)
{
ha=q.front();
int tx=ha.x1+dx[i],ty=ha.y1+dy[i];
if(1<=tx&&tx<=4&&1<=ty&&ty<=4&&(ha.now[tx][ty]+ha.color==3||ha.color==0))//可以下
{
ha.color=ha.now[tx][ty];
swap(ha.now[tx][ty],ha.now[ha.x1][ha.y1]);
ha.x1=tx,ha.y1=ty;
ha.hash=HASH(ha);
if(!vis[ha.hash])
{
vis[ha.hash]=1;
ha.step++;
q.push(ha);
}
}
ha=q.front();//queue
tx=ha.x2+dx[i],ty=ha.y2+dy[i];
if(1<=tx&&tx<=4&&1<=ty&&ty<=4&&(ha.now[tx][ty]+ha.color==3||ha.color==0))
{
ha.color=ha.now[tx][ty];
swap(ha.now[tx][ty],ha.now[ha.x2][ha.y2]);
ha.x2=tx,ha.y2=ty;
ha.hash=HASH(ha);
if(!vis[ha.hash])
{
vis[ha.hash]=1;
ha.step++;
q.push(ha);
}
}
q.pop();
}
}
int main()
{
int tmpx1,tmpx2,tmpy1,tmpy2;
for(int i=1;i<=4;i++)
{
cin>>a;
for(int j=0;j<4;j++)
{
if(a[j]=='B')
mp[i][j+1]=1;
else if(a[j]=='W')
mp[i][j+1]=2;
else if(!flag&&a[j]=='O') //第一个空位
{
flag=1;
mp[i][j+1]=0;
tmpx1=i;tmpy1=j+1;
}
else //第二个空位
{
mp[i][j+1]=0;
tmpx2=i;tmpy2=j+1;
}
}
}//处理mp
alice la;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
la.now[i][j]=mp[i][j];
la.color=0;la.x1=tmpx1;la.y1=tmpy1;la.x2=tmpx2;la.y2=tmpy2;la.step=0;la.hash=HASH(la);
vis[la.hash]=1;
q.push(la);
bfs();
printf("%d\n",ans);
return 0;
}
dfs版
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
string a;
int mp[5][5],ans=0x3f3f3f3f;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int vis[10000005],tmpx[3],tmpy[3];
bool can(int x,int y)
{
if(x < 1||x > 4) return false;
if(y < 1||y > 4) return false;
return true;
}
bool could()
{
for(int i=1;i<=4;i++)
{
if(mp[i][1]==mp[i][2]&&mp[i][2]==mp[i][3]&&mp[i][3]==mp[i][4]) return true;
if(mp[1][i]==mp[2][i]&&mp[3][i]==mp[2][i]&&mp[3][i]==mp[4][i]) return true;
}
if(mp[1][1]==mp[2][2]&&mp[2][2]==mp[3][3]&&mp[3][3]==mp[4][4]) return true;
if(mp[4][1]==mp[3][2]&&mp[3][2]==mp[2][3]&&mp[2][3]==mp[1][4]) return true;
return false ;
}
int pc(int clr)
{
int ret=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
ret=(ret*3+mp[i][j])%9999991;
return (ret*(clr+2))%9999991;
}
void dfs(int x1,int y1,int x2,int y2,int lastclr,int stp)
{
if(stp>ans) return ;
if(could())
{
ans=min(ans,stp);
return ;
}
for(int ii=1;ii<=2;ii++)
{
for(int i=0;i<4;i++)
{
int tx=dx[i]+x1,ty=dy[i]+y1;
if(can(tx,ty)&&lastclr+mp[tx][ty]==3)
{
swap(mp[tx][ty],mp[x1][y1]);
if(vis[pc(mp[x1][y1])]>stp+1||vis[pc(mp[x1][y1])]==0)
{
vis[pc(mp[x1][y1])]=stp+1;
dfs(tx,ty,x2,y2,mp[x1][y1],stp+1);
}
swap(mp[tx][ty],mp[x1][y1]);
}
}
swap(x1,x2);swap(y1,y2);
}
}
int main()
{
memset(vis,0,sizeof(vis));
bool flg=0;
int tmpx1,tmpy1,tmpx2,tmpy2,tot=0;
for(int i=1;i<=4;i++)
{
cin>>a;
for(int j=0;j<4;j++)
{
if(a[j]=='B') mp[i][j+1]=1;
else if(a[j]=='W') mp[i][j+1]=2;
else tmpx[++tot]=i,tmpy[tot]=j+1;
}
}
dfs(tmpx[1],tmpy[1],tmpx[2],tmpy[2],1,0);
dfs(tmpx[1],tmpy[1],tmpx[2],tmpy[2],2,0);
printf("%d\n",ans);
return 0;
}