BZOJ1085 SCOI2005 騎士精神

2022-02-05 23:08:57 字數 1529 閱讀 7001

在乙個5×5的棋盤上有12個白色的騎士和12個黑色的騎士, 且有乙個空位。在任何時候乙個騎士都能按照騎

士的走法(它可以走到和它橫座標相差為1,縱座標相差為2或者橫座標相差為2,縱座標相差為1的格仔)移動到空

位上。 給定乙個初始的棋盤,怎樣才能經過移動變成如下目標棋盤: 為了體現出騎士精神,他們必須以最少的步

數完成任務。

第一行有乙個正整數t(t<=10),表示一共有n組資料。接下來有t個5×5的矩陣,0表示白色騎士,1表示黑色騎

士,*表示空位。兩組資料之間沒有空行。

對於每組資料都輸出一行。如果能在15步以內(包括15步)到達目標狀態,則輸出步數,否則輸出-1。

210110

01*11

10111

01001

00000

01011

110*1

01110

01010

001007-1

暴力搜尋明顯會超時,因為步數不多,可以考慮迭代加深搜尋。

但是仍然過不去,需要a*剪枝。

本題大多數人的估價函式是不在應該在的位置上點的個數。

但是這個估價函式在只剩下一步就可以成功的時候是不成立的。

如果最後一步交換空格和乙個棋子使得為目標狀態,我們的估價函式的值是2,但是實際只需要一步,不滿足估價函式的定義。

所以真正的估價函式是上面得到的答案減1,但是這個估價函式距離真正答案的距離更大,效果沒有原本的好,實測估價函式僅少了1,卻慢了4倍!!

玄學的搜尋,玄學的剪枝啊!

#include #include 

#include

#include

using

namespace

std;

#define reg register

intt;

char mp[7][7

];bool

flag;

const

int tab[7][7] =,

, ,

, ,

};const

int dx=, dy=;

int a[7][7

];int

h()

intans;

void idastar(int dep, int x, int

y)

for (reg int i = 1 ; i <= 8 ; i ++)

}int

main()

}if (!h())

flag = 0

; ans = 1

;

for ( ; !flag and ans <= 16 ; ans++) idastar(0

, xx, yy);

if (ans == 17) puts("-1"

);

else printf("

%d\n

", ans - 1

); }

return0;

}

BZOJ 1085 SCOI 2005 騎士精神

之前聽說過ida 好像很優越啊。估價函式為不在目標位置的棋子個數。列舉一遍最大搜尋深度即可。還得好好斟酌一下要列舉的搜尋深度。344ms。include include using namespace std define rep i,j,k for int i j imaxdep return 0...

bzoj1085 SCOI2005 騎士精神

此題用到了a 演算法以及迭代加深搜尋。其實做本題之前看到過這個東西,發現估價什麼的好複雜,一直不會用。但應用於本題很容易就能實現,只要和最終結果一一比對即可。演算法如下,借鑑了hzwer大神的寫法。include include using namespace std int ans 5 5 int...

BZOJ1085 SCOI2005 騎士精神

在乙個5 5的棋盤上有12個白色的騎士和12個黑色的騎士,且有乙個空位。在任何時候乙個騎士都能按照騎 士的走法 它可以走到和它橫座標相差為1,縱座標相差為2或者橫座標相差為2,縱座標相差為1的格仔 移動到空 位上。給定乙個初始的棋盤,怎樣才能經過移動變成如下目標棋盤 為了體現出騎士精神,他們必須以最...