八数码问题(暴力)

紫书上的程序真是牛逼

用到了路径寻找之类,还有状态数组,bfs,按坐标寻路的数组。hash,编码解码。STL等

#include<cstdio>
#include<cstring>
#include<set>
#include<set>
using namespace std;
#define maxstate 1000000
typedef int State[9];
State st[maxstate] , goal;
int dist[maxstate];

const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};

const int hashsize = 1000003;
int head[hashsize], next[maxstate];
void init_lookup_table()  { memset(head,0,sizeof(head)); }
int hash(State& s){
    int v=0;
    for(int i=0;i<9;i++) v=v*10+s[i];
    return v%hashsize;
}
int try_to_insert(int s){
    int h=hash(st[s]);
    int u=head[h];
    while(u){
        if(memcmp(st[u],st[s],sizeof(st[s]))==0) return 0;
        u=next[u];
    }
    next[s]=head[h];
    head[h]=s;
    return 1;
}

/*set<int> vis;
void init_lookup_table() { vis.clear(); }
int try_to_insert(int s){
    int v=0;
    for(int i=0;i<9;i++)  v =v*10 + st[s][i];
    if(vis.count(v)) return 0;
    vis.insert(v);
    return 1;
}
*/
/*
int vis[362880], fact[9];
void init_lookup_table(){
    fact[0]=1;
    for(int i=1;i<9;i++) fact[i]=fact[i-1]*i;
}

int try_to_insert(int s){
    int code = 0;
    for(int i=0;i<9;i++){
        int cnt=0;
        for(int j=i+1;j<9;j++) if(st[s][j] < st[s][i]) cnt++;
        code += fact[8-i]*cnt;

    }
    if(vis[code]) return 0;
    return vis[code]=1;
}
*/
/*

2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
*/
int bfs(){
    init_lookup_table();
    int front=1,rear=2;
    while(front < rear){
        State &s = st[front];
        if( memcmp(goal, s, sizeof(s))==0 ) return front;
        int z;
        for(z=0;z<9;z++) if(!s[z]) break;
        int x=z/3,y=z%3;
//        printf("z=%d x=%d y=%d\n",z,x,y);
        for(int d=0;d<4;d++){

            int newx = x + dx[d];
            int newy = y + dy[d];
            int newz = newx*3 + newy;

            if(newx >= 0 && newx <=2 && newy>=0 && newy <=2)
            {

                State& t = st[rear];
                memcpy(&t,&s,sizeof(s));
                t[newz] = s[z];
                t[z]=s[newz];
                dist[rear] = dist[front] + 1;
                if(try_to_insert(rear)) {   rear++; }
            }

        }
        front++;
    }
    return 0;
}

int main()
{
    for(int i=0;i<9;i++) scanf("%d", &st[1][i]);
    for(int i=0;i<9;i++) scanf("%d", &goal[i]);
    int ans = bfs();
//    printf("%d\n",ans);
    if(ans > 0 ) printf("%d\n",dist[ans]);
    else printf("-1\n");
    return 0;
}
时间: 2024-11-10 15:42:27

八数码问题(暴力)的相关文章

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu

八数码的八境界 [转载]

八数码的八境界   研究经典问题,空说不好,我们拿出一个实际的题目来演绎.八数码问题在北大在线测评系统中有一个对应的题,题目描述如下: Eight Time Limit: 1000MS    Memory Limit: 65536K  Special Judge Description The 15-puzzle has been aroundfor over 100 years; even if you don't know it by that name, you've seen it. I

洛谷OJ P1379 八数码难题 解题报告

洛谷OJ P1379 八数码难题 解题报告 by MedalPluS 题目描述   在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变.   输入格式   输入初试状态,一行九个数字,空格用0表示   输出格式 只有一行,该行只有一个数字,表示从初始状态到

HDU 1043 POJ 1077 八数码问题

以下内容转载自:http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 八数码的八境界 研究经典问题,空说不好,我们拿出一个实际的题目来演绎.八数码问题在北大在线测评系统中有一个对应的题,题目描述如下: Eight Time Limit: 1000MS    Memory Limit: 65536K  Special Judge Description The 15-puzzle has been aroundfor ove

多种方法求解八数码问题

AI的实验报告,改了改发上来.希望路过的大牛不吝赐教.非常是纳闷我的ida*怎么还没有双搜快.还有发现基于不在位启示的A*和Ida*都挺慢.尤其是ida* 搜索31步的竟然要十几秒.是我写的代码有问题吗?忘路过的大牛指导啊!!!! 另外声明一下,有些东西也是看网上各路牛人的blog学来的,因为比較杂,再次无法一一列出,总之再次感谢把自己的思考的结果放到网上与大家分享的大牛们.谢谢! 八数码问题 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每一个棋子上标有1至8的某一数字,不同棋子上标

有很多种方法来解决八数码

AI实验报告,改变了重定向.希望通过翼牛. 我很纳闷ida*然而,如何快速的双搜索.还找到了灵感不在位的基础上A*和Ida*来到慢.特别ida* 搜索31步骤甚至十几秒.我写的代码是有问题?忘记丹尼尔路过指点啊.!! ! 另外声明一下,有些东西也是看网上各路牛人的blog学来的,因为比較杂,再次无法一一列出.总之再次感谢把自己的思考的结果放到网上与大家分享的大牛们.谢谢! 八数码问题 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每一个棋子上标有1至8的某一数字.不同棋子上标的数字不同

1225 八数码难题

1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765

洛谷【P1379】八数码难题

P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊

八数码三种用时差距极大的写法

进化史,一种比一种长,一种比一种快.不过第三种似乎还不是最终形态. 第一种,傻逼级迭代加深. 去年十一月写的,那时候刚刚学迭代加深,敲了一个钟头才敲完,codevs上直接过,就没太管,觉得这是个水题.实际上呢,看后文. 1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 int sx,sy,lim,

【转】八数码问题及A*算法

一.八数码问题八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤.所谓问题的一个状态就是棋子在棋盘上的一种摆法.棋子移动后,状态就会发生改变.解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态.八数码问题一般使用搜索法来解.搜索法有广度优先搜索法.深度优