题目链接:点击查看

题目大意:八数码经典问题,给出一个3*3的矩阵,其中随机分布着1~8的数字以及一个空位(我们用x来表示空位),在整个矩阵中,每一次操作都可以将x和他附近的方块互换,问经过多少次操作可以将当前的状态变为顺序状态,即

1   2   3

4   5   6

7   8   x

求所需操作的最小次数以及每次的步骤

题目分析:一看到这个题目首先想到每一种情况都可以表示为一种状态,一提到状态我们就可以用bfs进行展开,这个题不得不说我优化了一个下午,一开始没多想,直接用A*做的,想连一下A*算法,结果写完之后T掉了,我就感觉我的估价函数找的不太对,就去网上搜了大佬的博客,比这写了一下估价函数,结果变成WA了,有点自闭,就去网上搜了搜八种方法解八数码问题,就选了现在的这个,先用bfs打个表,然后就可以O(1)查询了,省去了大量的bfs步骤,不过我在打表的时候用到了unordered_map,但是poj不让用这个东西。。所以在poj上还是T掉了,在hdu上的以200多ms的时间A掉了,我又试了试用map交了一发,在hdu上还是A了,只不过时间变成了500ms。。因为网上的正解都是用了康托展开维护状态的,但我不会,只能用最菜的map来维护所谓的双向哈希了,预处理bfs打个路径表,然后直接问什么输出什么就可以了

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=4e5+100;const int b[4][2]={0,1,0,-1,1,0,-1,0};const char p[5]="lrud";const string target="123456780";unordered_map<string,int>vis;struct Node
{int pre;int dir;Node(int PRE,int DIR){pre=PRE;dir=DIR;}Node(){}
}path[N];void bfs()
{int cnt=0;//用一个cnt变量辅助维护模拟链表vis.clear();queue<string>q;q.push(target);//以最终状态为起点,bfs展开即可,时间复杂度为9!,不到4e5path[cnt].pre=-1;path[cnt].dir=-1;vis[target]=cnt++;while(!q.empty()){string cur=q.front();q.pop();int pos;for(pos=0;pos<9;pos++)if(cur[pos]=='0')break;int x=pos/3;int y=pos%3;for(int i=0;i<4;i++){int xx=x+b[i][0];int yy=y+b[i][1];if(xx<0||yy<0||xx>=3||yy>=3)continue;int ppos=xx*3+yy;string temp=cur;swap(temp[pos],temp[ppos]);if(vis[temp])continue;path[cnt].pre=vis[cur];path[cnt].dir=i;vis[temp]=cnt++;q.push(temp);}}
}//2 3 4
//1 5 x
//7 6 8int main()
{
//  freopen("input.txt","r",stdin);bfs();//预处理打表char s[5];while(scanf("%s",s)!=EOF){string str;if(s[0]=='x')str+='0';elsestr+=s[0];for(int i=0;i<8;i++){scanf("%s",s);if(s[0]=='x')str+='0';elsestr+=s[0];}if(!vis[str])//如果该状态遍历不到,则无解printf("unsolvable\n");else//如果该状态能遍历到,则直接输出路径即可{int k=vis[str];while(k!=-1){putchar(p[path[k].dir]);k=path[k].pre;}putchar('\n');}}return 0;
}

HDU - 1043 Eight(bfs打表)相关推荐

  1. hdu 5179(bfs打表+二分)

    beautiful number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. HDU 1043 Eight(八数码)

    HDU 1043 Eight(八数码) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  3. hdu 1043 Eight 经典八数码问题

    hdu 1043 Eight 经典八数码问题 题意描述:给出一个3×3的矩阵(包含1-8数字和一个字母x),经过一些移动格子上的数后得到连续的1-8,最后一格是x,要求最小移动步数. 算法分析:经典的 ...

  4. hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数

    题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的. 思路: ...

  5. HDU 6555 The Fool(打表整除分块)

    HDU 6555 The Fool(打表&整除分块) 1.打表,找规律.发现是3-5-7-然后等差数列求和特判即可. 2.整除分块,复杂度O(n)O(\sqrt{n})O(n​) code l ...

  6. Eight HDU - 1043

    Eight HDU - 1043 题意:给定一个3*3的方阵,要求通过交换x方格与其相邻方格位置的方式,使方阵上的数字由小到大排列,且x在右下角.输出具体交换步骤

  7. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  8. hdu 1043 ,pku 1077 Eight ,八数码问题

    某位神牛曾说过,此题是涉及到人生完不完整的一道题.. Goodness大牛曾总结了 八数码的八重境界 : http://www.cnblogs.com/goodness/archive/2010/05 ...

  9. hdu 1043 Eight 搜索,哈希

    很早之前做过,总结一下康拓展开哈希大法.当初要是懂了这玩意北京网赛那题一定能出.... http://acm.hdu.edu.cn/showproblem.php?pid=1043题目链接 http: ...

最新文章

  1. Go 学习笔记(70)— Go 变量声明、变量初始化、值类型变量赋值、指针类型变量赋值
  2. 如何让LINUX程序运行在多CPU?
  3. Lucene.net常见功能实现知识汇总
  4. Logistic regression--转
  5. 黑神话:悟空中演示视频中一些设计浅析与建议
  6. 某法院HP-P4500存储数据恢复案例
  7. openwrt 遍译php_openwrt安装编译
  8. 80--查询分组关联属性
  9. 总结之《征服C指针》
  10. python 简单检索器_python实现文件搜索工具(简易版)
  11. ssis行计数变量_SSIS服务性能计数器指南
  12. 怎么同时连接内外网?
  13. windows消息钩子
  14. 天大2021年秋学期考试《画法几何及工程制图》离线作业考核试题
  15. uniity3d进行磕碰检测并在磕碰时发送音讯
  16. 美国迈阿密二手房房价预测
  17. 开源推荐 - CoDo开源一站式DevOps平台
  18. 基于树莓派实现简易-智能家居
  19. GPS导航仪的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  20. C语言打印多颜色字体,多功能打印,协助开发调试

热门文章

  1. Nginx的rewrite之break指令
  2. 怎么获取插入的最新自动生成的ID
  3. MyBatis 实际使用案例-typeHandlers【重点】
  4. Spring IOC 容器根据Bean 名称或者类型进行autowiring 自动依赖注入
  5. 为什么需要Redis 集群
  6. 引导类、扩展类、系统类加载器的使用及演示
  7. 模块-基本概念和import导入复习
  8. 摆放家具-家具类以及创建家具对象
  9. Activemq-In-action(三)
  10. C语言创建指针需要给大小吗,如何用c语言创建一个指针(示例代码)