A - Eight
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:
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:
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.
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.
InputYou will receive, several descriptions of configuration of the 8 puzzle. One 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
OutputYou 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. Do not print a blank line between cases.
Sample Input
2 3 4 1 5 x 7 6 8Sample Output
ullddrurdllurdruldr
1.一种超内存的方法
1 /* 2 HDU 1043 Eight 3 思路:反向搜索,从目标状态找回状态对应的路径 4 用康托展开判重 5 */ 6 #include<stdio.h> 7 #include<string.h> 8 #include<iostream> 9 #include<queue> 10 #include<string> 11 using namespace std; 12 const int MAXN=1000000;//最多是9!/2 13 int fac[]={1,1,2,6,24,120,720,5040,40320,362880};//康拖展开判重 14 // 0!1!2!3! 4! 5! 6! 7! 8! 9! 15 bool vis[MAXN];//标记 16 string path[MAXN];//记录路径 17 int cantor(int s[])//康拖展开求该序列的hash值 18 { 19 int sum=0; 20 for(int i=0;i<9;i++) 21 { 22 int num=0; 23 for(int j=i+1;j<9;j++) 24 if(s[j]<s[i])num++; 25 sum+=(num*fac[9-i-1]); 26 } 27 return sum+1; 28 } 29 struct Node 30 { 31 int s[9]; 32 int loc;//“0”的位置 33 int status;//康拖展开的hash值 34 string path;//路径 35 }; 36 int move[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//u,d,l,r 37 char indexs[5]="durl";//和上面的要相反,因为是反向搜索 38 int aim=46234;//123456780对应的康拖展开的hash值 39 void bfs() 40 { 41 memset(vis,false,sizeof(vis)); 42 Node cur,next; 43 for(int i=0;i<8;i++)cur.s[i]=i+1; 44 cur.s[8]=0; 45 cur.loc=8; 46 cur.status=aim; 47 cur.path=""; 48 queue<Node>q; 49 q.push(cur); 50 path[aim]=""; 51 while(!q.empty()) 52 { 53 cur=q.front(); 54 q.pop(); 55 int x=cur.loc/3; 56 int y=cur.loc%3; 57 for(int i=0;i<4;i++) 58 { 59 int tx=x+move[i][0]; 60 int ty=y+move[i][1]; 61 if(tx<0||tx>2||ty<0||ty>2)continue; 62 next=cur; 63 next.loc=tx*3+ty; 64 next.s[cur.loc]=next.s[next.loc]; 65 next.s[next.loc]=0; 66 next.status=cantor(next.s); 67 if(!vis[next.status]) 68 { 69 vis[next.status]=true; 70 next.path=indexs[i]+next.path; 71 q.push(next); 72 path[next.status]=next.path; 73 } 74 } 75 } 76 77 } 78 int main() 79 { 80 char ch; 81 Node cur; 82 bfs(); 83 while(cin>>ch) 84 { 85 if(ch=='x') {cur.s[0]=0;cur.loc=0;} 86 else cur.s[0]=ch-'0'; 87 for(int i=1;i<9;i++) 88 { 89 cin>>ch; 90 if(ch=='x') 91 { 92 cur.s[i]=0; 93 cur.loc=i; 94 } 95 else cur.s[i]=ch-'0'; 96 } 97 cur.status=cantor(cur.s); 98 if(vis[cur.status]) 99 { 100 cout<<path[cur.status]<<endl; 101 } 102 else cout<<"unsolvable"<<endl; 103 } 104 return 0; 105 }
2.
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<iostream> using namespace std; const int MAXN=400000; bool has[MAXN]; int fac[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; int dx[] = {-1, 0, 1, 0}; int dy[] = {0, -1, 0, 1}; int last[MAXN]; short int mov[MAXN]; struct State{ short int s[9]; short int pos; int hash; }ini; queue<State> q; int Hash(short int *s) { int res=0; for(int i=0;i<8;i++) { int cnt=0; for(int j=i+1;j<9;j++) if(s[i]>s[j]) cnt++; res +=cnt*fac[8-i]; } return res; } int cal_pos(int pos,int i) { int nx=pos/3+dx[i],ny=pos%3+dy[i]; if(nx<0||nx>2||ny<0||ny>2) return -1; return nx*3+ny; } void BFS() { State target; for(int i=0;i<9;i++) target.s[i] = i+1; target.pos=8; target.hash=0; has[0]=1; q.push(target); while(!q.empty()) { State ha = q.front(); q.pop(); State tmp; for(int i=0;i<4;i++) { tmp.pos=cal_pos(ha.pos,i); if(tmp.pos<0) continue; for(int j=0;j<9;j++) { if(j==ha.pos) tmp.s[j]=ha.s[tmp.pos]; else if(j==tmp.pos) tmp.s[j]=ha.s[ha.pos]; else tmp.s[j]=ha.s[j]; } tmp.hash = Hash(tmp.s); if(has[tmp.hash]) continue; q.push(tmp); has[tmp.hash]=1; last[tmp.hash]=ha.hash; mov[tmp.hash]=i; } } } void print_path(int x) { if(x==0) return ; int i=mov[x]; if(!i) printf("d"); else if(i==1) printf("r"); else if(i==2) printf("u"); else printf("l"); print_path(last[x]); } int main() { memset(has,0,sizeof(has)); BFS(); char tmp; while(cin>>tmp) { if(tmp!='x') ini.s[0]=tmp-'0'; else { ini.s[0]=9; ini.pos=0; } for(int i=1;i<9;i++) { cin>>tmp; if(tmp=='x') { ini.s[i]=9; ini.pos=i; } else ini.s[i]=tmp-'0'; } ini.hash=Hash(ini.s); if(!has[ini.hash]) printf("unsolvable"); else print_path(ini.hash); puts(""); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!