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

HDU 1043 八数码(八境界)

时间:2016-07-11 10:19:37      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

8境界:http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html

境界一、 暴力广搜+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;
}

 

境界三、广搜+哈希+打表(HDU 263ms,POJ C++797ms,POJ G++579ms)

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

从最终状态(0)开始进行BFS。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;

char t[1000];
int c[10];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char path[10]={d,u,r,l};
char op[5],input[20];

struct Node
{
    int s,p;
    Node(){}
    Node(int S,int P){s=S,p=P;}
};

struct Path
{
    int from,dir;
}pa[400000];
bool f[400000];

int getnum()
{
    int res=0;
    for(int i=0;t[i];i++)
        for(int j=i+1;t[j];j++)
            if(t[j]<t[i]) res=res+c[8-i];
    return res;
}

void getstr(int val)
{
    int tmp[10],flag[10];
    memset(flag,0,sizeof flag);
    for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
    for(int i=0;i<9;i++)
    {
        int num=0;
        for(int j=0;j<9;j++)
        {
            if(flag[j]==0) num++;
            if(num==tmp[i]+1)
            {
                t[i]=j+0+1; if(t[j]==9) t[j]=x;
                flag[j]=1;break;
            }
        }
    }
}

void pre()
{
    queue<Node>Q;
    Q.push(Node(0,8));
    f[0]=1; pa[0].from=-1,pa[0].dir=-1;

    while(!Q.empty())
    {
        Node h=Q.front(); Q.pop();
        int a=h.p/3, b=h.p%3; getstr(h.s);
        for(int i=0;i<4;i++)
        {
            int x=a+dir[i][0],y=b+dir[i][1];
            if(!(x>=0&&x<=2&&y>=0&&y<=2)) continue;
            int newpos=3*x+y;
            swap(t[newpos],t[h.p]);
            int news=getnum();
            if(f[news]) {swap(t[newpos],t[h.p]);continue;}
            pa[news].from=h.s, pa[news].dir=i, f[news]=1;
            Q.push(Node(news,newpos));
            swap(t[newpos],t[h.p]);
        }
    }
}

int main()
{
    c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
    pre();

    while(~scanf("%s",op))
    {
        t[0]=op[0];
        for(int i=1;i<=8;i++) {scanf("%s",op); t[i]=op[0];}
        int state=getnum();
        if(f[state]==0) printf("unsolvable\n");
        else
        {
            while(1)
            {
                if(pa[state].from==-1) break;
                printf("%c",path[pa[state].dir]);
                state=pa[state].from;
            }
            printf("\n");
        }
    }
    return 0;
}

 

HDU 1043 八数码(八境界)

标签:

原文地址:http://www.cnblogs.com/zufezzt/p/5659276.html

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