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

八数码八境界代码

时间:2017-03-23 10:39:43      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:closed   for   无法   continue   数据   状态   逆序   algorithm   out   

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

一个状态表示成一维的形式,求出除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;
}
View Code

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

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

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

 

八数码八境界代码

标签:closed   for   无法   continue   数据   状态   逆序   algorithm   out   

原文地址:http://www.cnblogs.com/mhpp/p/6603807.html

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