HDU 1043 Eight BFS

题意:就是恢复成1,2,3,4,5,6,7,8,0;

分析:暴力BFS预处理,所有路径,用康拓展开判重,O(1)打印 93ms 还是很快的

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N=5005;
int fac[]= {1,1,2,6,24,120,720,5040,40320,362880};
int aim;
int cantor(char s[])
{
    int ans=0;
    for(int i=1,j=8; i<=9; ++i,--j)
    {
        int tmp=0;
        for(int k=i+1; k<=9; ++k)
            if(s[i]>s[k])++tmp;
        ans+=(tmp*fac[j]);
    }
    return ans;
}
struct Node
{
    char s[10];
    int hs;
};
struct asd
{
   bool vis;
   char c;
   int pre;
}o[362880];
queue<Node>q;
void bfs()
{
    Node a;
    for(int i=1; i<=8; ++i)
        a.s[i]=‘0‘+i;
    a.s[9]=‘0‘;
    aim=a.hs=cantor(a.s);
    o[aim].vis=1;
    q.push(a);
    while(!q.empty())
    {
        a=q.front();
        q.pop();
        int now=a.hs;
        int x;
        for(int i=1; i<=9; ++i)
            if(a.s[i]==‘0‘)x=i;
        if(x-3>0)
        {
            bool flag=0;
            swap(a.s[x],a.s[x-3]);
            a.hs=cantor(a.s);
           if(o[a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[a.hs].vis=1;
                o[a.hs].c=‘d‘;
                o[a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x-3]);
        }
        if(x+3<10)
        {
            bool flag=0;
            swap(a.s[x],a.s[x+3]);
            a.hs=cantor(a.s);
            if(o[a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[a.hs].vis=1;
                o[a.hs].c=‘u‘;
                o[a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x+3]);
        }
        if(x%3!=1)
        {
            bool flag=0;
            swap(a.s[x],a.s[x-1]);
            a.hs=cantor(a.s);
            if(o[a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[a.hs].vis=1;
                o[a.hs].c=‘r‘;
                o[a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x-1]);
        }
        if(x%3)
        {
            bool flag=0;
            swap(a.s[x],a.s[x+1]);
            a.hs=cantor(a.s);
           if(o[a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[a.hs].vis=1;
                o[a.hs].c=‘l‘;
                o[a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x+1]);
        }
    }
}
char str[30],tmp[10];
void print(int u)
{
    while(u!=aim)
    {
       printf("%c",o[u].c);
       u=o[u].pre;
    }
    printf("\n");
}
int main()
{
    for(int i=0;i<326880;++i)
      o[i].vis=0;
    bfs();
    while(gets(str))
    {
        int l=0;
        for(int i=0; str[i]!=‘0‘; ++i)
        {
            if(str[i]==‘x‘)tmp[++l]=‘0‘;
            else if(str[i]>=‘1‘&&str[i]<=‘9‘)tmp[++l]=str[i];
        }
        int ans=cantor(tmp);
        if(!o[ans].vis)
            printf("unsolvable\n");
        else
            print(ans);
    }
    return 0;
}

时间: 2024-08-07 08:40:31

HDU 1043 Eight BFS的相关文章

HDU 1043 Eight (BFS&#183;八数码&#183;康托展开)

题意  输出八数码问题从给定状态到12345678x的路径 用康托展开将排列对应为整数  即这个排列在所有排列中的字典序  然后就是基础的BFS了 #include <bits/stdc++.h> using namespace std; const int N = 5e5, M = 9; int x[4] = { -1, 1, 0, 0}; int y[4] = {0, 0, -1, 1}; int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320

Eight HDU - 1043 (双向BFS)

记得上人工智能课的时候老师讲过一个A*算法,计算估价函数(f[n]=h[n]+g[n])什么的,感觉不是很好理解,百度上好多都是用逆向BFS写的,我理解的逆向BFS应该是从终点状态出发,然后把每一种状态打表列举出来,最后O(1)查询就可以了.这种办法确实挺好,但是不会..... 这位大佬用的双向BFS https://blog.csdn.net/qq_41670466/article/details/84110090,挺好理解的,但是注释什么的比较少,也没有过多的介绍思路,所以我想借助这篇blo

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

HDU 1043 Eight(八数码)

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

HDU - 1043 - Eight / POJ - 1077 - Eight

先上题目: Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11243    Accepted Submission(s): 3022Special Judge Problem Description The 15-puzzle has been around for over 100 years; even if you

[ACM] hdu 1242 Rescue (BFS+优先队列)

Rescue Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison. Angel's friends want to save Angel. Their task is:

hdu 4856 Tunnels(bfs+状态压缩)

题目链接:hdu 4856 Tunnels 题目大意:给定一张图,图上有M个管道,管道给定入口和出口,单向,现在有人想要体验下这M个管道,问最短需要移动的距离,起点未定. 解题思路:首先用bfs处理出两两管道之间移动的距离,然后后用状态压缩求出最短代价,dp[i][j],i表示的已经走过的管道,j是当前所在的管道. #include <cstdio> #include <cstring> #include <queue> #include <algorithm&g

hdu 1104 数论+bfs

题意:给n,m,k;输出n经过+-*%后(n%k+k)%k==((n+1)%k)%k  输出最小路径与运算副 zsd:% 只是求余数 有正负 mod 是求模 无正负. yhd:对m*k求余对 对k求余不对 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 5

HDU 1495——非常可乐( BFS )

非常可乐 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4663    Accepted Submission(s): 1868 Problem Description 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要