1054: [HAOI2008]移动玩具
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2810 Solved: 1574
Description
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动
时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移
动到某人心中的目标状态。
Input
前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空
行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。
Output
一个整数,所需要的最少移动次数。
Sample Input
1111
0000
1110
0010
1010
0101
1010
0101
Sample Output
4
代码:
直接广搜即可,但是注意要判重,判重的方法可采用转化成字符串。
PS:unordered_map真是个好东西。
代码:
#include <bits/stdc++.h>
#include<tr1/unordered_map>
using namespace std;
using namespace std::tr1;
const int Max=1000010;
const int fx[5]={0,1,0,-1,0};
const int fy[5]={0,0,1,0,-1};
int n,m,head,tail=1;
char s[5][5],t[5][5];
struct shu{char a[5][5];int step;};
shu p[Max];
unordered_map<string, bool>Hash;
inline string getstring(char ch[5][5])
{
string ans="";
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
ans+=ch[i][j];
return ans;
}
inline int check(char ch[5][5])
{
int flag=1;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(ch[i][j] != t[i][j]) flag=0;
return flag;
}
inline int bfs()
{
memcpy(p[1].a,s,sizeof(s));
Hash[getstring(s)]=1;
while(head<tail)
{
head++;
for(register int i=1;i<=4;i++)
for(register int j=1;j<=4;j++)
{
if(p[head].a[i][j] == '1')
{
for(register int k=1;k<=4;k++)
{
int x=i+fx[k],y=j+fy[k];
if(x<=0||x>4||y<=0||y>4) continue;
if(p[head].a[x][y]=='0')
{
char c[5][5];
memcpy(c,p[head].a,sizeof(p[head].a));
c[i][j]='0',c[x][y]='1';
if(!Hash.count(getstring(c)))
{
if(check(c)) return p[head].step+1;
Hash[getstring(c)]=1;
p[++tail].step=p[head].step+1;
memcpy(p[tail].a,c,sizeof(c));
}
}
}
}
}
}
}
int main()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++) scanf("%c",&s[i][j]);
scanf("\n");
}
scanf("\n");
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++) scanf("%c",&t[i][j]);
scanf("\n");
}
int x=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(s[i][j] == t[i][j]) x++;
if(x==16) cout<<"0\n";
else cout<<bfs()<<"\n";
return 0;
}