洛谷OJ P1379 八數碼難題 解題報告

2022-09-04 13:15:13 字數 2450 閱讀 8833

by medalplus

題目描述

在3×3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是:給出一種初始布局(初始狀態)和目標布局(為了使題目簡單,設目標狀態為123804765),找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。

輸入格式

輸入初試狀態,一行九個數字,空格用0表示

輸出格式

只有一行,該行只有乙個數字,表示從初始狀態到目標狀態需要的最少移動次數(測試資料中無特殊無法到達目標狀態資料)

分析

其實就是個裸的bfs,但是可以拓展很多知識點(有人說不做這題的人的oi人生不完美)

暴力bfs的話會被卡,因為要搜尋的狀態實在太多了

所以這裡有兩種優化:

1.啟發式搜尋

我們假設f=g+h,那麼g可以設為已經挪動的步數,h為不在位將牌個數,這樣就構建了乙個估價函式

然後直接寫就好

2.雙向bfs

我們知道起點和終點,直接雙向就好

另外,這裡應該如何判重呢?其實很簡單,下面引入康托展開:

然後就利用康托值進行判重就好

**

1 #include 2 #include 3 #include 4 #include 5

using

namespace

std;67

#define rep(i,l,r) for(i=l;i<=r;i++)

8const

int maxn=10;9

const

int maxm=1000001;//

9!*8+8!*7...<=5000001

1011

struct

node

15}head,tail;

1617

short

intvis_f[maxm],vis_b[maxm];

18int

tmps[maxn];

19 queuef,b;

2021

int fact(int

x)26

27int cantor(node now)

41return

res;42}

4344

void

init_front()

5051

void

init_back()

5758

void

init()

6465

void

expand_f()

78 tmp=head;

79if(sx-1>0)83

if(vis_f[cantor(tmp)]==-1)87

}88 tmp=head;

89if(sx+1

<=3)93

if(vis_f[cantor(tmp)]==-1)97

}98 tmp=head;

99if(sy-1>0

)103

if(vis_f[cantor(tmp)]==-1

)107

}108 tmp=head;

109if(sy+1

<=3

)113

if(vis_f[cantor(tmp)]==-1

)117

}118

}119

120void

expand_b()

133 tmp=head;

134if(sx-1>0

)138

if(vis_b[cantor(tmp)]==-1

)142

}143 tmp=head;

144if(sx+1

<=3

)148

if(vis_b[cantor(tmp)]==-1

)152

}153 tmp=head;

154if(sy-1>0

)158

if(vis_b[cantor(tmp)]==-1

)162

}163 tmp=head;

164if(sy+1

<=3

)168

if(vis_b[cantor(tmp)]==-1

)172

}173

}174

175void

double_bfs()

185else

189}

190}

191192

intmain()

**量比較大,竟然有個小200....

洛谷OJ P1379 八數碼難題(雙向搜尋)

思路 相信不少小夥伴上來就是暴力dfs,但是拿到題之後我們不妨想一想如果純dfs爆搜下來會產生多少種狀態,這樣的方法是否是最優的?這裡選擇使用一種稱之為雙向搜尋的方法 通過知乎學到的,放出來share一下 具體來說就是若已知初始狀態和終止狀態下我們同時從起點和終點開始dfs 當然也有bfs寫法,這裡...

洛谷 1379 八數碼難題

題目 八數碼難題 思路 bfs hash判重。注意 1 hash的鍊錶不能寫錯。2 由於用的是一位陣列,所以移動時要判斷左右邊界。比如當前的空位在5處,就不能向右移 1。0 1 2 3 4 5 6 7 8 include include include include include include...

洛谷 1379 八數碼難題

在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布局 初始狀態 和目標布局 為了使題目簡單,設目標狀態為123804765 找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。輸入格...