八数码八境界代码

判断无解的情况(写完七种境界才发现有直接判断无解的方法):

一个状态表示成一维的形式,求出除0之外所有数字的逆序数之和,也就是每个数字前面比它大的数字的个数的和,称为这个状态的逆序。

若两个状态的逆序奇偶性相同,则可相互到达,否则不可相互到达。

POJ提交记录(从下往上依次为第1,2,3,4,5,6,7,8境界):

本文转自:http://www.cnblogs.com/zufezzt/p/5659276.html

HDU提交记录(从下往上依次为第1,2,3,4,5,6,7,8境界):

PS:因为HDU是多组测试数据,所以一般POJ上要100ms以上才能AC的方法,在HDU上是无法通过的(境界3除外)

境界一、 暴力广搜+STL (HDU 内存超限,POJ 时间超限)

map存路径,set判重,string存状态,毫无疑问,炸了。

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#include<iostream>
using namespace std;

char input[1000];
int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
string d = "durl";
set<string>f;
map<string, string>m;
int sz = 0;

struct node
{
    string s;
    string path;
    int pos;

    node() {}
    node(string str, string pa, int Pos)
    {
        s = str;
        path = pa;
        pos = Pos;
    }
};

bool g(int a, int b)
{
    if (a >= 0 && a <= 2 && b >= 0 && b <= 2) return 1;
    return 0;
}

void pre()
{
    queue<node>q;
    q.push(node("12345678x", "", 8));
    m["12345678x"] = "";
    f.insert("12345678x");

    while (!q.empty())
    {
        node h = q.front(); q.pop();
        int a = h.pos / 3, b = h.pos % 3;
        for (int i = 0; i<4; i++)
        {
            int x = a + dir[i][0], y = b + dir[i][1];
            if (!g(x, y)) continue;
            int pos = 3 * x + y;
            swap(h.s[h.pos], h.s[pos]);
            if (f.find(h.s) != f.end())
            {
                swap(h.s[h.pos], h.s[pos]);
                continue;
            }
            q.push(node(h.s, d[i] + h.path, pos));
            f.insert(h.s);
            m[h.s] = d[i] + h.path;
            swap(h.s[h.pos], h.s[pos]);
        }
    }

}

int main()
{
    pre();
    while(~scanf("%s",input))
    {
        string v="";
        v = v + input[0];
        for (int i = 1; i <= 8; i++)
        {
            scanf("%s", input);
            v = v + input[0];
        }
        if (m[v] == "") cout << "unsolvable" << endl;
        else cout << m[v] << endl;
    }

    return 0;
}

境界二、广搜+哈希(POJ 453ms)

利用康托展开对状态进行hash,hash值对应0--(9!-1),因此可以开数组判重,路径的记录可以记录到达某状态的最后一步操作是什么与父节点是什么。

从输入的状态开始进行BFS,直到找到最终状态。

时间: 2024-10-13 16:21:53

八数码八境界代码的相关文章

hdu 1034 Eight 传说中的八数码问题。真是一道神题,A*算法+康托展开

Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13506    Accepted Submission(s): 3855 Special Judge Problem Description The 15-puzzle has been around for over 100 years; even if you don'

搜索进阶1、八数码(HDU1043)

http://acm.hdu.edu.cn/showproblem.php?pid=1043 八数码八境界: https://www.cnblogs.com/zufezzt/p/5659276.html 借用了MAP哈希,发现只能过hdu(249ms),poj一直TLE. 还是先上个代码吧,以后再改用康拓展开来哈希.. 1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<

使用Muduo完成数独和八数码问题求解服务器

在剖析完Muduo网络库源码之后,我们试着完成一个高效的数独和八数码问题求解服务器. 先说说为什么要选择这两个问题?数独问题一直是陈硕老师很喜欢的问题,在muduo网络库中多次提到并有示例.八数码问题是我很喜欢的问题,所以在此综合完成求解数独和八数码问题的高效服务端程序. 编写这样一个看似简单的服务程序的技术含量远高于所谓的控件堆砌型开发,虽然有muduo网络库帮助我们处理网络事件,我们只需要关注setConnectionCallback() 和setMessageCallback() 事件,但

八数码的八境界 [转载]

八数码的八境界   研究经典问题,空说不好,我们拿出一个实际的题目来演绎.八数码问题在北大在线测评系统中有一个对应的题,题目描述如下: 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

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

1225 八数码难题

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

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

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

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

HDU 3567 Eight II(八数码 II)

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-size: 10.5000pt } h1 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: center; font-family: 宋体; color: rgb(26,92,200); font-weight: bold; fo