搜索进阶1、八数码(HDU1043)

http://acm.hdu.edu.cn/showproblem.php?pid=1043

八数码八境界:

https://www.cnblogs.com/zufezzt/p/5659276.html

借用了MAP哈希,发现只能过hdu(249ms),poj一直TLE。

还是先上个代码吧,以后再改用康拓展开来哈希。。

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<string.h>
  4 #include<cstring>
  5 #include<iostream>
  6 #include<queue>
  7 #include<set>
  8 #include<math.h>
  9 #include<vector>
 10 #include<functional>
 11 #include<queue>
 12 #include<map>
 13 #define MAXN 100005
 14 typedef long long ll;
 15 using namespace std;
 16
 17 int fx[4][2]={1,0,-1,0,0,-1,0,1};
 18 char sum[400000][40]={0};
 19 char *lu="dulr";
 20 typedef struct Node{
 21     int x,y,num;
 22 }node;
 23 map<int,int>mp;
 24 int tot=0;
 25
 26 void pre()
 27 {    queue<node>qe;
 28     sum[0][0]=‘\0‘;
 29
 30     qe.push((node){2,2,123456789});
 31     while(!qe.empty())
 32     {
 33         node t=qe.front();
 34         qe.pop();
 35         int mt[3][3];
 36         int numt=t.num;
 37         for(int i=2;i>=0;i--)
 38         for(int j=2;j>=0;j--)
 39         {
 40             mt[i][j]=numt%10;
 41             numt/=10;
 42         }
 43         for(int i=0;i<4;i++)
 44         {
 45             int tx=t.x+fx[i][0];
 46             int ty=t.y+fx[i][1];
 47             if(!(tx>=0&&tx<=2&&ty>=0&&ty<=2)) continue;
 48             swap(mt[tx][ty],mt[t.x][t.y]);
 49             int numx=0;
 50             for(int i=0;i<3;i++)
 51             for(int j=0;j<3;j++)
 52             {
 53                 numx=numx*10+mt[i][j];
 54             }
 55             swap(mt[tx][ty],mt[t.x][t.y]);
 56             if(mp[numx]>0) continue;
 57
 58              mp[numx]=++tot;
 59             strcpy(sum[tot],sum[mp[t.num]]);
 60             int l=strlen(sum[tot]);
 61             sum[tot][l]=lu[i],sum[tot][l+1]=‘\0‘;
 62             qe.push((node){tx,ty,numx});
 63
 64         }
 65     }
 66
 67
 68
 69 }
 70 void reverse(char *s)
 71 {
 72     int l=strlen(s);
 73     if(l==0)
 74     {
 75         printf("unsolvable\n");
 76         return;
 77     }
 78     for(int i=l-1;i>=0;i--)
 79     {
 80         if(s[i]==‘u‘) putchar(‘d‘);
 81         else if(s[i]==‘d‘) putchar(‘u‘);
 82         else if(s[i]==‘l‘) putchar(‘r‘);
 83         else if(s[i]==‘r‘) putchar(‘l‘);
 84     }
 85     printf("\n");
 86 }
 87
 88
 89 int main()
 90 {    pre();
 91
 92     char s[50];
 93     while(gets(s)!=NULL)
 94     {    int num=0;
 95         for(int i=0;s[i];i++)
 96         {
 97             if(s[i]>=‘1‘&&s[i]<=‘8‘)
 98             {
 99                 num=num*10+s[i]-‘0‘;
100             }
101             if(s[i]==‘x‘)
102             {
103                 num=num*10+9;
104             }
105         }
106
107         reverse(sum[mp[num]]);
108     }
109     return 0;
110 } 

原文地址:https://www.cnblogs.com/lnu161403214/p/8552294.html

时间: 2024-10-08 16:10:32

搜索进阶1、八数码(HDU1043)的相关文章

ACM/ICPC算法训练 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题是: 给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤. 所谓问题的一个状态就是棋子在棋盘上的一种摆法.棋子移动后,状态就会发生改变.解八数码问题就是找出从初状态到目标状态所经过的一系列中间状态.八数码问题一

八数码问题:C++广度搜索实现

毕竟新手上路23333,有谬误还请指正. 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限制又会有很多情况无法找到,然后果断放弃,改用广度搜索.  如果要改善代码效率还可以用双向搜索,即从起始状态和最终状态同时搜索,找到相同状态,这样搜索时间会缩短一半.此外还可以用A*(启发式算法)会显得高端很多. 题目要求: 在一个3*3的棋盘上,随机放置1到8的数字棋子,剩下一个空位.数字可以移动到

八数码问题——双向广度优先搜索解决

八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移.空格右移.空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态. 搜索顺序有两种: (1)两个方向交替进行扩展 (2)每次选择节点少的那个扩展 一般来说方法(2)可以克服两端生长不平衡的现象 // eight.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> #include&l

HDU 1043 八数码(A*搜索)

在学习八数码A*搜索问题的时候需要知道以下几个点: Hash:利用康托展开进行hash 康托展开主要就是根据一个序列求这个序列是第几大的序列. A*搜索:这里的启发函数就用两点之间的曼哈顿距离进行计算就可以. 减枝:在八数码里,任意交换一个空行和一个位置的数字,这个八数码的逆序数是不变的,这样就可以根据目前状态判断是否可达终点状态了. 第一次做这个题用的map进行哈希,结果果断超时,之后又写了LRJ书上的hash方法也超时了,最后只能用康托展开了 详细请参考:[八数码的八重境界] http://

HDU1043 八数码(BFS + 打表)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界:http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 我自己是用哈希(康托展开) + BFS  + 打表过的,第三重境界. 由于一些高级的搜索现在还没学,所以目前能升级的也就是用双向BFS来做了,等过几天有心情了来做. 本文

codevs1225八数码难题(搜索&#183;)

1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最

广度优先搜索解决八数码问题

八数码简介 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每一个棋子上标有1至8的某一数字,不同棋子上标的数字不同样.棋盘上另一个空格,与空格相邻的棋子能够移到空格中.要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤.所谓问题的一个状态就是棋子在棋盘上的一种摆法.棋子移动后,状态就会发生改变.解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态. 求解八数码问题要懂得的知识 1.康托展开,八数码在交换的过程

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu

搜索进阶

搜索进阶的话,我觉得A*,IDA*,双向BFS应该都是吧. 双向BFS就是同时从起点和终点开始BFS,直到遇到对方标记的结点就停止(这样应该不一定是最短路),这样的话只要有解就可以减去很多种可能,从而提高效率. 不过如果没解的话,两边的搜索没有交叉,也就...会更慢... 然后就是A*,这算是人工智能里面的了吧...就是F(n)=G(n)+H(n),这里G一般就是节点的深度,也就是走了多少步走到了这里,H的话就是一个估计,估计还有差不多多少步就会走完,然后这两个加起来,作为一个依据,那么下一次要