思路:一眼丁真,鉴定为,春春的宽搜
用一个string的01串记录当前的一个局面,每一种情况的16个位置都要尝试去扩展四个方向,遇到合法且没扩展过的就入队,这里获取某一个旗子的坐标使用当前01字符在串中的下标表示。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef pair<int,int>PII;
typedef long long ll;
string st ,ed;
map<string,int>dist;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int bfs()
{
queue<string >q;
q.push(st);
dist[st]=0;
while(q.size())
{
string t=q.front();
string p;
q.pop();
for(int i=0;i<16;i++)
for(int j=0;j<4;j++)
{
p=t;
int x=i/4+dx[j];
int y=i%4+dy[j];
if(x<0||x>3||y<0||y>3||p[i]==p[4*x+y])continue;
swap(p[i],p[4*x+y]);
if(dist[p]==0)
{
q.push(p);
dist[p]=dist[t]+1;
}
if(p==ed)
return dist[p];
}
}
return -1;
}
int main()
{
string a;
for(int i=1;i<=4;i++)
{
cin>>a;
st=st+a;
}
for(int i=1;i<=4;i++)
{
cin>>a;
ed=ed+a;
}
if(st==ed)
cout<<0<<endl;
else
cout<<bfs()<<endl;
return 0;
}