隐式图的遍历。

大意:在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 < 5return 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;
}

 

posted on 2012-10-11 21:44  有间博客  阅读(409)  评论(0编辑  收藏  举报