Description
Input
Output
Sample Input
1111
0000
1110
0010
0000
1110
0010
Sample Output
4
分析:dalao都说是水题,但我是真的不知道还有这种姿势的暴搜,涨见识了。这道题感觉来当hash+bfs的模板题好像很合适的样子。好了hash+bfs,其实就是把队列中的存点改成存图,只要队列中存到与答案相同的图,就一定是最优的(广搜性质不用说吧),至于如何判断是否与要求一样,或者是这张图走过没有,就直接给每张图个hash值每次判断是否为true就好了(map要开始装b了)
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <cmath>
# include <list>
# include <queue>
# include <map>
using namespace std;
typedef long long ll;
int read()
{
int f=1,i=0;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
i=(i<<3)+(i<<1)+ch-'0';
ch=getchar();
}
return f*i;
}
struct data
{
int a[5][5];
int step;
}q[1000005];
struct node
{
int x,y;
node(){}
node(int x,int y) : x(x),y(y){}
};
char ch[5][5];
int a[5][5],b[5][5],ans,s,t;
map<ll,bool>hash;
int judge(int a[5][5])
{
int k=1,sum=0;
for(int i=1;i<=4;++i)
for(int j=1;j<=4;++j)
{sum+=k*a[i][j];k<<=1;}
return sum;
}
node go(node p,int i)
{
if(i==1) p.x--;
if(i==2) p.x++;
if(i==3) p.y--;
if(i==4) p.y++;
return p;
}
inline void BFS(int t)
{
int head=0,tail=1;
while(head<tail)
{
for(int i=1;i<=4;++i)
for(int j=1;j<=4;++j)
if(q[head].a[i][j])
for(int k=1;k<=4;++k)
{
node now=go(node(i,j),k);
if(now.x<1||now.x>4||now.y<1||now.y>4||q[head].a[now.x][now.y]) continue;
swap(q[head].a[i][j],q[head].a[now.x][now.y]);
int flag=judge(q[head].a);
if(!hash[flag])
{
if(flag==t)
{
printf("%d\n",q[head].step+1);
return;
}
hash[judge(q[head].a)]=1;
memcpy(q[tail].a,q[head].a,sizeof(q[tail].a));
q[tail].step=q[head].step+1;
++tail;
}
swap(q[head].a[i][j],q[head].a[now.x][now.y]);
}
++head;
}
}
int main()
{
for(int i=1;i<=4;++i)
{
scanf("%s",ch[i]);
for(int j=0;j<4;++j)
q[0].a[i][j+1]=ch[i][j]-'0';
}
for(int i=1;i<=4;++i)
{
scanf("%s",ch[i]);
for(int j=0;j<4;++j)
b[i][j+1]=ch[i][j]-'0';
}
s=judge(q[0].a),t=judge(b);
if(s==t)
{
printf("0\n");return 0;
}
hash[s]=1;BFS(t);
}
那个说一下,memecpy比for循环赋值快,所以搜到新图直接cpy就好了。好像有dalao跑了spfa?还有这种操作?感觉好高级的样子,有兴趣可以去搜一搜。