HDU 3567 Eight II BFS预处理

题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么

分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法

预处理打表,因为八数码问题实际上是每个小块位置的变化,上面的数字只是用来标记位置的,

所以通过映射将初末序列进行置换就好了,然后因为每次的x字符的置换位置不一样

所以需要以123456789这个初始串打9遍表就好了733ms

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#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[10][362880];
queue<Node>q;
void bfs(int pos)
{
    Node a;
    for(int i=1; i<=9; ++i)
        a.s[i]=‘0‘+i;
    aim=a.hs=cantor(a.s);
    o[pos][a.hs].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‘+pos)x=i;
        if(x+3<10)
        {
            bool flag=0;
            swap(a.s[x],a.s[x+3]);
            a.hs=cantor(a.s);
            if(o[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=‘d‘;
                o[pos][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[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=‘l‘;
                o[pos][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[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=‘r‘;
                o[pos][a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x+1]);
        }
        if(x-3>0)
        {
            bool flag=0;
            swap(a.s[x],a.s[x-3]);
            a.hs=cantor(a.s);
           if(o[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=‘u‘;
                o[pos][a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x-3]);
        }
    }
}
char s[15],t[15];
string res;
void getres(int u,int pos)
{
    while(u!=aim)
    {
       res=res+o[pos][u].c;
       u=o[pos][u].pre;
    }
}
char mat[13];
int main()
{
    for(int i=0;i<326880;++i)
     for(int j=1;j<=9;++j)
      o[j][i].vis=0;
    for(int i=1;i<=9;++i)
       bfs(i);
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
         scanf("%s%s",s+1,t+1);
         int flag;
         for(int i=1;i<=9;++i)
         {
             if(s[i]==‘X‘)s[i]=‘9‘,flag=i;
             if(t[i]==‘X‘)t[i]=‘9‘;
             mat[s[i]-‘0‘]=i+‘0‘;
         }
         for(int i=1;i<=9;++i)
            t[i]=mat[t[i]-‘0‘];
        int ans=cantor(t);
        res.clear();
        getres(ans,flag);
        printf("Case %d: %d\n",++cas,res.size());
        reverse(res.begin(),res.end());
        cout<<res<<endl;
    }
    return 0;
}

时间: 2024-12-20 17:09:29

HDU 3567 Eight II BFS预处理的相关文章

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

HDU 3533 Escape(BFS+预处理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 题目大意:给你一张n* m的地图,人在起点在(0,0)要到达终点(n,m)有k(k<=100)座炮台,每座炮台都有各自的发射方向.发射周期和发射速度,每隔一段时间会发射一定速度的炮弹,人每秒可以选择停在原地或者往上下左右走,问是否能在时间d之内安全到达终点.如果可以,请输出最短时间. 解题思路:BFS+预处理,分为以下几点: ①预处理,用step[x][y][t]记录(x,y)在时间t是否被炮

HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3

http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过,而且也不好控制字典序 换个角度想,虽然起始状态有很多,但是到底哪一位是1,哪一位是2不是最重要的,最重要的是和目标状态对应,所以可以把起始状态重新编码为"12345678"这种形式(先不考虑X),然后目标状态也对应过去,当考虑X的时候,我们可以认为起始状态只有9种,分别是'X'在各个位置的

HDU 3567 Eight II

Eight II Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 356764-bit integer IO format: %I64d      Java class name: Main Eight-puzzle, which is also called "Nine grids", comes from an old game. In this ga

HDU - 3567 Eight II IDA*

Eight-puzzle, which is also called "Nine grids", comes from an old game. In this game, you are given a 3 by 3 board and 8 tiles. The tiles are numbered from 1 to 8 and each covers a grid. As you see, there is a blank grid which can be represente

HDU-2128-Tempter of the Bone II(BFS)

Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze was changed and the way he came in was lost.He realized that the bone was a trap, and he tried desperately to get out

hdu 5147 Sequence II(树状数组)

题目链接:hdu 5147 Sequence II 预处理每个位置作为b和c可以组成的对数,然后枚举b的位置计算. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 50005; int N, arr[maxn], fenw[maxn], lef[maxn], rig[maxn]; #d

HDU 3081Marriage Match II(二分+并查集+网络流之最大流)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3081 有一段时间没写最大流的题了,这题建图居然想了好长时间...刚开始是按着最终的最大流即是做多轮数去想建图,结果根本没思路,后来想了想,可以用二分答案的思想来找最终答案.然后很明显的并查集,但是并查集学的略渣,居然卡在并查集上了..= =. 但是也不是并查集的事..是我建图的思想太正了,稍微用点逆向思维并查集就可以很好利用了. 建图思路是:建立一个源点与汇点,将女孩与源点相连,男孩与汇点相连,权值

HDU 4856 Tunnels(BFS+状压DP)

HDU 4856 Tunnels 题目链接 题意:给定一些管道,然后管道之间走是不用时间的,陆地上有障碍,陆地上走一步花费时间1,求遍历所有管道需要的最短时间,每个管道只能走一次 思路:先BFS预处理出两两管道的距离,然后状态压缩DP求解,dp[s][i]表示状态s,停在管道i时候的最小花费 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using