luoguP1379 八数码难题[IDA*]

Posted ZYBGMZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP1379 八数码难题[IDA*]相关的知识,希望对你有一定的参考价值。

题目描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入输出格式

输入格式:

输入初试状态,一行九个数字,空格用0表示

输出格式:

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

输入输出样例

输入样例#1:
283104765
输出样例#1:
4


 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 using namespace std;
 6 
 7 //目标态 
 8 int fin[9][2]={{1,1},{0,0},{0,1},{0,2},{1,2},{2,2},{2,1},{2,0},{1,0}};
 9 
10 struct State{
11     int a[3][3];
12 };
13 
14 int lim=0,ok;
15 
16 //计算f(n)函数 
17 int H(const State &st){
18     int ret=0;
19     for(int i=0;i<3;i++)
20         for(int j=0;j<3;j++){
21             int t=st.a[i][j];
22             if(t)  ret+=abs(fin[t][0]-i)+abs(fin[t][1]-j);
23         }
24     return ret;
25 }
26 
27 void dfs(State st,int g){
28     int h=H(st);
29     if(ok||g+h>lim)
30         return;
31     if(!h){
32         ok=1;
33         return;
34     }
35     int x,y;
36     for(int i=0;i<3;i++)
37         for(int j=0;j<3;j++)
38             if(!st.a[i][j]){
39                 x=i,y=j;
40                 break;
41             }
42     if(x>0){
43         swap(st.a[x][y],st.a[x-1][y]);
44         dfs(st,g+1);
45         swap(st.a[x][y],st.a[x-1][y]);
46     }
47     if(x<2){
48         swap(st.a[x][y],st.a[x+1][y]);
49         dfs(st,g+1);
50         swap(st.a[x][y],st.a[x+1][y]);
51     }
52     if(y>0){
53         swap(st.a[x][y],st.a[x][y-1]);
54         dfs(st,g+1);
55         swap(st.a[x][y],st.a[x][y-1]);
56     }
57     if(y<2){
58         swap(st.a[x][y],st.a[x][y+1]);
59         dfs(st,g+1);
60         swap(st.a[x][y],st.a[x][y+1]);
61     }
62 }
63 
64 int main(){
65     State st;
66     char ch[10];
67     scanf("%s",ch);
68     for(int i=0;i<3;i++)
69         for(int j=0;j<3;j++)
70             st.a[i][j]=ch[i*3+j]-0;
71     while(++lim){
72         dfs(st,0);
73         if(ok)  break;
74     }
75     printf("%d\n",lim);
76     return 0;
77 }

 


在写盲目bfs 1590ms 后很久才用的IDA*解法
感谢will7101在luogu上题解给本蒟蒻此题IDA*稍短代码的启蒙
终于学会了计算h(n)    QwQ
 

总是在梦里我看到你无助的双眼  我的心又一次被唤醒

以上是关于luoguP1379 八数码难题[IDA*]的主要内容,如果未能解决你的问题,请参考以下文章

「 Luogu P1379 」 八数码难题

[LGOJ]P1379八数码难题[双向广搜].cpp

P1379 八数码难题

洛谷P1379八数码难题

洛谷 P1379 八数码难题

luogu_1379 八数码难题