方法同样是bfs ,不过判重用了STL里的set。算是比较基础的bfs题吧。
#include<cstdio>
#include<queue>
#include<set>
#include<cstring>
using namespace std;
struct state
{
int x;
int y;
int step;
char sta[5][5];
}start,q;
int xx,yy;//记录起始空格的位置
int dx[] = {-1, 1, -2, 2, -1, 1, -2, 2};
int dy[] = {-2, -2, -1, -1, 2, 2, 1, 1};
char goal[5][5] = { '1','1','1','1','1',
'0','1','1','1','1',
'0','0',' ','1','1',
'0','0','0','0','1',
'0','0','0','0','0'};//记录目标状态
struct cmp
{
bool operator() (state a ,state b) const
{
return memcmp(a.sta,b.sta,25)<0;
}
};
set <state,cmp> vis;
queue<state> que;
void init_lookup_table()
{
while (!que.empty()) que.pop();
vis.clear();
}
int try_to_insert(state s)
{
if (vis.count(s)) return 0;
vis.insert(s);
return 1;
}
void bfs(state &p)
{
init_lookup_table();
if (memcmp(p.sta, goal, sizeof(goal)) == 0)
{
printf("Solvable in 0 move(s).\n");
return;
}
que.push(p);
while (! que.empty())
{
p = que.front();
que.pop();
if (p.step >= 11)
{
printf("Unsolvable in less than 11 move(s).\n");
return;
}
if (memcmp(p.sta, goal, sizeof(p.sta)) == 0)
{
printf("Solvable in %d move(s).\n", p.step);
return;
}
for (int i = 0; i < 8; i ++)
{
q = p;
q.x += dx[i];
q.y += dy[i];
q.step ++;
if (q.x < 0 || q.x >= 5 || q.y < 0 || q.y >= 5) continue;
char tmp = q.sta[p.x][p.y];
q.sta[p.x][p.y] = q.sta[q.x][q.y];
q.sta[q.x][q.y] = tmp;
if (try_to_insert(q)) que.push(q);
}
}
return;
}
int main()
{
int n;
scanf("%d",&n);
getchar();
while(n--)
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
scanf("%c",&start.sta[i][j]);
if(start.sta[i][j]==' ') {xx=i;yy=j;}
}
getchar();
}
start.x=xx , start.y=yy;
start.step=0;
bfs(start);
}
return 0;
}