隐式图的遍历。
大意:在5X5方格中,给你一定的棋子,让你判断找出最小的步数变成给定的状态。
思路:BFS+hash判重模拟过程。
1、通过STL重载来实现hash
struct cmp
{
bool operator () (int a, int b) const
{
return memcpy(a.map, b.map, 25) < 0;
}
};
2、hash判重,注意状态转移。
CODE:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <
set>
using
namespace std;
struct node
{
int x, y, step;
char map[
5][
5];
}p, q;
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() (node a, node b)
const
{
return memcmp(a.map, b.map,
25) <
0;
}
};
//
重载
queue<node> Q;
set<node, cmp> vis;
int bx, by;
int check(
int r,
int c)
{
if(r >=
0 && r <
5 && c >=
0 && c <
5)
return
1;
return
0;
}
void init()
{
while(!Q.empty()) Q.pop();
vis.clear();
}
int try_to_insert(node s)
{
if(vis.count(s))
return
0;
vis.insert(s);
return
1;
}
//
hash
void bfs(node &p)
{
init();
if(memcmp(p.map, goal,
sizeof(goal)) ==
0)
{
printf(
"
Solvable in 0 move(s).\n
");
return ;
}
Q.push(p);
while(!Q.empty())
{
p = Q.front(); Q.pop();
if(p.step >=
11)
{
printf(
"
Unsolvable in less than 11 move(s).\n
");
return ;
}
if(memcmp(p.map, goal,
sizeof(goal)) ==
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(!check(q.x, q.y))
continue;
char tmp = q.map[p.x][p.y];
q.map[p.x][p.y] = q.map[q.x][q.y];
q.map[q.x][q.y] = tmp;
//
模拟状态转移过程
if(try_to_insert(q))
{
Q.push(q);
}
}
}
return ;
}
int main()
{
int T;
scanf(
"
%d
", &T);
getchar();
while(T--)
{
for(
int i =
0; i <
5; i++)
{
for(
int j =
0; j <
5; j++)
{
scanf(
"
%c
", &p.map[i][j]);
if(p.map[i][j] ==
'
')
{
bx = i;
by = j;
}
}
getchar();
}
p.x = bx, p.y = by, p.step =
0;
bfs(p);
}
return
0;
}