浅学八数码 poj1077

Eight

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 26261   Accepted: 11490   Special Judge

Description

The 15-puzzle has been around for over 100 years; even if you don‘t know it by that name, you‘ve seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let‘s call the missing tile ‘x‘; the object of the puzzle is to arrange the tiles so that they are ordered as:

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15  x 

where the only legal operation is to exchange ‘x‘ with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:

 1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4
 5  6  7  8    5  6  7  8    5  6  7  8    5  6  7  8
 9  x 10 12    9 10  x 12    9 10 11 12    9 10 11 12
13 14 11 15   13 14 11 15   13 14  x 15   13 14 15  x
           r->           d->           r-> 

The letters in the previous row indicate which neighbor of the ‘x‘ tile is swapped with the ‘x‘ tile at each step; legal values are ‘r‘,‘l‘,‘u‘ and ‘d‘, for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and 
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing ‘x‘ tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three 
arrangement.

Input

You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus ‘x‘. For example, this puzzle

 1  2  3
 x  4  6
 7  5  8 

is described by this list:

 1 2 3 x 4 6 7 5 8 

Output

You will print to standard output either the word ``unsolvable‘‘, if the puzzle has no solution, or a string consisting entirely of the letters ‘r‘, ‘l‘, ‘u‘ and ‘d‘ that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.

Sample Input

 2  3  4  1  5  x  7  6  8 

Sample Output

ullddrurdllurdruldr

Source

South Central USA 1998

第一次的代码:

bfs+康拓展开;

略有点粗糙,晚上交一发,直接过了,但是时间不是很理想,明天再改进一下。

Accepted 24600K 63MS C++ 3370B 2015-05-09 00:58:11

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstring>
  5 using namespace std;
  6
  7 int hehe[3][3]={1,2,6,24,120,720,5040,40320,362880};
  8 int hehe2[9]={1,2,6,24,120,720,5040,40320,362880};
  9 char w[4]={‘r‘,‘l‘,‘u‘,‘d‘};
 10 int dx[]={0,0,-1,1};
 11 int dy[]={1,-1,0,0};
 12 class Matrix
 13 {
 14 private:
 15     int t[3][3];
 16     int x0,y0;
 17     int d;
 18     int last;
 19 public:
 20     void Set_value(int x,int y,char *s);
 21     void Set_x(int tx){x0=tx;}
 22     void Set_y(int ty){y0=ty;}
 23     void Set_Deal(int a) { d=a; }
 24     void Set_Last(int w){last=w;}
 25     int Get_Deal() { return d;  }
 26     int Get_Last(){return last; }
 27     int Get_x(){return x0;}
 28     int Get_y(){return y0;}
 29     void Swap(int x1,int y1,int x2,int y2)
 30     {
 31         int e=t[x1][y1];
 32         t[x1][y1]=t[x2][y2];
 33         t[x2][y2]=e;
 34     }
 35     int Get_value(int x,int y) { return t[x][y];  }
 36     int Get_hash();
 37     void operator = (Matrix & w)
 38     {
 39         for(int i=0;i<3;i++)
 40             for(int j=0;j<3;j++)
 41                 t[i][j]=w.t[i][j];
 42         x0=w.x0;
 43         y0=w.y0;
 44     }
 45     void Show()
 46     {
 47         for(int i=0;i<3;i++,cout << endl)
 48             for(int j=0;j<3;cout << t[i][j] << " ",j++);
 49     }
 50 };
 51 int Matrix::Get_hash()
 52 {
 53     int rev=0;
 54     for(int i=0;i<3;i++)
 55         for(int j=0;j<3;j++)
 56             rev+=t[i][j]*hehe[i][j];
 57     return rev;
 58 }
 59 void Matrix::Set_value(int x,int y,char *s)
 60 {
 61     if(!isdigit(s[0]))
 62     {
 63         t[x][y]=0;
 64         x0=x,y0=y;
 65     }
 66     else
 67     {
 68         int len=strlen(s),c=0;
 69         for(int i=0;i<len;i++)
 70             c=c*10+s[i]-‘0‘;
 71         t[x][y]=c;
 72     }
 73 }
 74 int vis[4000000];
 75 Matrix Mx[10000000];
 76 int Ans=0;
 77 void output(int now)
 78 {
 79     if(Mx[now].Get_Last()==-1) return;
 80     else
 81     {
 82         output(Mx[now].Get_Last());
 83         printf("%c",w[Mx[now].Get_Deal()]);
 84     }
 85 }
 86 bool check(int x,int y)
 87 {
 88     if(x>=0&&x<=2&&y>=0&&y<=2) return true;
 89     return false;
 90 }
 91 void bfs()
 92 {
 93     memset(vis,0,sizeof(vis));
 94     vis[Mx[0].Get_hash()]=1;
 95     Mx[0].Set_Deal(-1);
 96     Mx[0].Set_Last(-1);
 97     int Start=1;
 98     int End=0;
 99     while(End<Start)
100     {
101         Matrix mx;
102         mx=Mx[End++];
103         int nx=mx.Get_x();
104         int ny=mx.Get_y();
105         for(int i=0;i<4;i++)
106         {
107             int tx=nx+dx[i];
108             int ty=ny+dy[i];
109             if(check(tx,ty))
110             {
111                 mx.Swap(nx,ny,tx,ty);
112                 mx.Set_x(tx),mx.Set_y(ty);
113                 int temp=mx.Get_hash();
114                 if(vis[temp]==0)
115                 {
116                     vis[temp]=1;
117                     Mx[Start]=mx;
118                     Mx[Start].Set_Deal(i);
119                     Mx[Start].Set_Last(End-1);
120                     if(temp==Ans)
121                     {
122                         output(Start);
123                         printf("\n");
124                         return;
125                     }
126                     Start++;
127                 }
128                 mx.Swap(nx,ny,tx,ty);
129                 mx.Set_x(nx),mx.Set_y(ny);
130             }
131         }
132     }
133     printf("unsolvable\n");
134 }
135 int main()
136 {
137     for(int i=0;i<8;i++)  Ans+=(i+1)*hehe2[i];
138     char temp[10];
139     for(int i=0;i<3;i++)
140         for(int j=0;j<3;j++)
141         {
142             scanf("%s",temp);
143             Mx[0].Set_value(i,j,temp);
144         }
145     bfs();
146     return 0;
147 }
148 //注释下次一起写

时间: 2024-10-17 00:19:50

浅学八数码 poj1077的相关文章

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

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

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

八数码三种用时差距极大的写法

进化史,一种比一种长,一种比一种快.不过第三种似乎还不是最终形态. 第一种,傻逼级迭代加深. 去年十一月写的,那时候刚刚学迭代加深,敲了一个钟头才敲完,codevs上直接过,就没太管,觉得这是个水题.实际上呢,看后文. 1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 int sx,sy,lim,

多种方法求解八数码问题

AI的实验报告,改了改发上来.希望路过的大牛不吝赐教.非常是纳闷我的ida*怎么还没有双搜快.还有发现基于不在位启示的A*和Ida*都挺慢.尤其是ida* 搜索31步的竟然要十几秒.是我写的代码有问题吗?忘路过的大牛指导啊!!!! 另外声明一下,有些东西也是看网上各路牛人的blog学来的,因为比較杂,再次无法一一列出,总之再次感谢把自己的思考的结果放到网上与大家分享的大牛们.谢谢! 八数码问题 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每一个棋子上标有1至8的某一数字,不同棋子上标

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

有很多种方法来解决八数码

AI实验报告,改变了重定向.希望通过翼牛. 我很纳闷ida*然而,如何快速的双搜索.还找到了灵感不在位的基础上A*和Ida*来到慢.特别ida* 搜索31步骤甚至十几秒.我写的代码是有问题?忘记丹尼尔路过指点啊.!! ! 另外声明一下,有些东西也是看网上各路牛人的blog学来的,因为比較杂,再次无法一一列出.总之再次感谢把自己的思考的结果放到网上与大家分享的大牛们.谢谢! 八数码问题 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每一个棋子上标有1至8的某一数字.不同棋子上标的数字不同

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来做了,等过几天有心情了来做. 本文

1225 八数码难题

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

洛谷【P1379】八数码难题

P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊