time limit: 10 sec
memory limit: 162 mb
submit: 1996
solved: 1121 [
submit][
status][
discuss]
在乙個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
題目大意:
如題。思路:
拿到這個題目,大致是乙個搜尋,分析一下:每次8個狀態, 15步,正常搜尋下去肯定炸。所以要進行非正常搜尋。
按照啟發式搜尋的思路,我們來給每個搜尋節點估價,如果搜尋當前節點 不能在規定花費內達到,就直接捨棄當前節點。
那麼我們按照什麼準則來估價呢?
在這個題目中,我們去比較 當前搜尋節點的棋子 和 最後完成的那個節點的差了多少,因為一步只能移動乙個棋子,如果我們發現在規定步數之內無法到達,就捨棄當前節點。
為什麼在搜尋的過程中,我們要去列舉步數呢?也即是列舉最後的答案。
因為 dfs是乙個一直到底的搜尋,到達最後的情況的路徑也有多條,我們需要找到最短的那個路徑,所以列舉dfs 的層數,在每個層數裡面去檢索答案。
當然 bfs 很適合做這種事情,(但是dfs 寫起來簡單)所以讓我用 bfs 再來寫一下這個題目吧。先給出 dfs **
ac**:
dfs
#include using namespace std;
inline void swap(int &a, int &b)
const int dx[8]= , dy[8]= ;
int mb[6][6]=
, ,,,
,};int s[6][6], ans, flag;
int haha;
inline bool check()
inline bool f(const int &g)
return true;
}void dfs(const int &x, const int &y, const int &g)
}if(flag) return;
for(int i=0;i<8;i++)
}int main()
}flag=0;
for(ans=1; ans<=15; ans++)
if(flag) printf("%d\n", ans);
else printf("-1\n");
}return 0;
}
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的格仔 移動到空 位上。給定乙個初始的棋盤,怎樣才能經過移動變成如下目標棋盤 為了體現出騎士精神,他們必須以最...