您的位置:首页 > 编程语言 > C语言/C++

bzoj 1054: [HAOI2008]移动玩具.cpp

2017-06-16 21:37 435 查看

1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2260  Solved: 1254

[Submit][Status][Discuss]

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

比较麻烦的广搜,用二进制表示状态

例如状态:

0101

1111

0000

1111

先将其转化成一行:0101111100001111,接下来求出该二进制下的十进制数即可

很显然,最多不超过2^16-1(65535)个状态

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
typedef struct
{
int str[6][6];
int step;
}State;
State temp, now;
queue<State> q;
int str[6][6], ed[6][6], flag[65536], dir[4][2] = {0,1,1,0,0,-1,-1,0};
int main(void)
{
int i, j, k, sum, b, c, dx, dy;
while(scanf("%1d", &c)!=EOF)
{
memset(str, -1, sizeof(str));
memset(ed, -1, sizeof(ed));
memset(flag, 0, sizeof(flag));
dx = dy = 0;
for(i=1;i<=4;i++)
{
for(j=1;j<=4;j++)
{
if(i==1 && j==1)
str[i][j] = c;
else
scanf("%1d", &str[i][j]);
dx += str[i][j];
}
}
for(i=1;i<=4;i++)
{
for(j=1;j<=4;j++)
scanf("%1d", &ed[i][j]), dy += ed[i][j];
}
if(dx!=dy)
{
printf("-1\n");
continue;
}
sum = 0;
for(i=1;i<=4;i++)
{
for(j=1;j<=4;j++)
sum *= 2, sum += ed[i][j];
}
flag[sum] = 7;
sum = 0;
for(i=1;i<=4;i++)
{
for(j=1;j<=4;j++)
sum *= 2, sum += str[i][j];
}
if(flag[sum]==7)
{
printf("0\n");
continue;
}
flag[sum] = 1;
memcpy(now.str, str, sizeof(str));
now.step = 0;
q.push(now);
while(q.empty()==0)
{
now = q.front();
q.pop();
temp.step = now.step+1;
for(i=1;i<=4;i++)
{
for(j=1;j<=4;j++)
{
if(now.str[i][j]==0)
{
for(k=0;k<=3;k++)
{
dx = i+dir[k][0];
dy = j+dir[k][1];
if(now.str[dx][dy]!=1)
continue;
memcpy(temp.str, now.str, sizeof(str));
swap(temp.str[i][j], temp.str[dx][dy]);
sum = 0;
for(b=1;b<=4;b++)
{
for(c=1;c<=4;c++)
sum *= 2, sum += temp.str[b][c];
}
if(flag[sum]==0)
{
flag[sum] = 1;
q.push(temp);
}
else if(flag[sum]==7)
{
while(q.empty()==0)
q.pop();
goto loop;
}
}
}
}
}
}
loop:printf("%d\n", temp.step);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: