码迷,mamicode.com
首页 > 其他好文 > 详细

八数码问题

时间:2015-01-14 20:03:31      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:acm   c++   stl   typedef   hash   

解八数码问题。


/*编号为1-8的8个正方形滑块被摆成3行3列(空一格),
每次可以把与空格相邻的滑块移到空格中!
而它原来的位置就变成了空格!
任务就是计算出最少的移动步数,如果无法移动到目标局面,就输出-1!
*/
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1001314;
int dx[4]= {1,0,-1,0};
int dy[4]= {0,1,0,-1};
int head[maxn],next[maxn],dis[maxn];
typedef int A[9];
A aa[maxn],goal;
void init()
{
    memset(head,0,sizeof(head));
}
int hash(A& s)
{
    int sum=0;
    for(int i=0; i<9; i++)
    {
        sum=sum*10+s[i];
    }//把九个数组合成9位数
    return sum%maxn;//确保hash函数值是不超过hash表的大小的非负整数
}
bool insert(int s)//使用哈希表、
{
    int h=hash(aa[s]);//从表头开始查找链表
    int u=head[h];
    while(u)
    {
        if(memcmp(aa[u],aa[s],sizeof(aa[s]))==0)
            return false;//找到了,插入失败
        u=next[u];//顺着链表继续找
    }
    next[s]=head[h];//插入到链表中
    head[h]=s;
    return true;
}
int bfs()
{
    init();//初始化
    int begin=1,end=2;
    while(begin<end)
    {
        A& now=aa[begin];
        if(memcmp(now,goal,sizeof(now))==0)//如果找到最终状态,则返回最终状态的下标。
            return begin;
        int point;
        for(point=0; point<9; point++)
            if(now[point]==0)//找到0所在的编号
                break;
        for(int i=0; i<4; i++)
        {
            int x=point/3,y=point%3;
            int new_x=x+dx[i];
            int new_y=y+dy[i];
            int new_point=new_x*3+new_y;//新滑块的编号
            if(new_x>=0&&new_y>=0&&new_x<3&&new_y<3)
            {//如果没有越出边界
                A& te=aa[end];
                memcpy(&te,&now,sizeof(now));
                te[point]=now[new_point];
                te[new_point]=now[point];
                //交换新滑块和空格的位置,即编号
                dis[end]=dis[begin]+1;//更新步数。
                if(insert(end))
                    end++;
            }
        }
        begin++;
    }
    return 0;//没有办法变成最终状态
}
int main()
{
    for(int i=0; i<9; i++)
        cin>>aa[1][i];//起始状态
    for(int i=0; i<9; i++)
        cin>>goal[i];//最终状态
    int ans=bfs();//返回最终状态的下标
    if(ans>0)
        cout<<dis[ans]<<endl;
    else
        cout<<-1<<endl;
    return 0;
}
/*
2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
*/


八数码问题

标签:acm   c++   stl   typedef   hash   

原文地址:http://blog.csdn.net/u014004096/article/details/42713379

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!