SCOI2005 騎士精神

2021-08-28 16:36:35 字數 1010 閱讀 9690

乙個比較直接的思路是bfs爆搜,但這樣只能拿20分,所以考慮優化。

在測試樣例時能夠看到深度為7的時候很快就跑出來了,在結合本題最大深度是15,所以可以用雙向bfs來優化,即從兩邊各跑7或8的深度,最後用map合併,有點類似折半搜尋。另外有一些需要注意的小細節已經在**中注釋。

code:

#include#include#include#includeusing namespace std;

struct state ;

mapm;

int t;

int dx[8]=, dy[8]=;

string aim="111110111100*110000100000";

bool bfs(int x, int y, string s) );

m[s]=1;

while (!q.empty())

for (int i=0; i<8; i++) );

}} }

return false;

}void bfss(int x, int y, string s) );

ms[s]=true;

while (!q.empty())

for (int i=0; i<8; i++)

if (!ms[tmp]) );

ms[tmp]=true;

}} }

}int main()

}s+=tmp;

} if (!bfs(x, y, s)) bfss(3, 3, aim);

} return 0;

}

ps:本題好像還可以用a*或者ida*來解。

簡單來說下:a*的估價函式就是當前我們已走步數加上剩餘未歸位的騎士-1的個數(樂觀估計,-1是因為將空格也看在內了,而有空格在樂觀估計的情況下就會出現一步使空格和騎士都歸位的情況),若這個數值大於15的話,那麼就不合法。

ida*就是在限制深度嘍, 這樣可以在整個搜尋樹深度很大而答案深度又很小的情況下大大提高效率。

SCOI2005 騎士精神

輸入格式 第一行有乙個正整數t t 10 表示一共有n組資料。接下來有t個5 5的矩陣,0表示白色騎士,1表示黑色騎士,表示空位。兩組資料之間沒有空行。輸出格式 對於每組資料都輸出一行。如果能在15步以內 包括15步 到達目標狀態,則輸出步數,否則輸出 1。輸入樣例 1 複製2 10110 01 1...

SCOI2005 騎士精神

qwq,ida 演算法太好玩了!在這裡放一波我對迭代加深搜尋 a 演算法的理解 不一定對 迭代加深搜尋就是列舉dfs的最大深度,然後跑dfs,去驗證不超過此深度的前提下是否有解 多用於答案上界很小或是搜尋範圍沒有上界,其實就是防止了dfs一搜到底。a 演算法看起來像是乙個剪枝,定義估價函式,樂觀地估...

SCOI2005 騎士精神 IDA

棋盤太大,狀態數太多,無法像八數碼那樣用雜湊 bfs去做,但是用dfs也會t掉,這個時候可以考慮ida 即 迭代加深搜尋 a 剪枝。這題的h n 就是當前與目標棋盤不同的棋子數量。在一顆含有答案的子樹中,我們至多需要再走h n 步,就可以找到答案 因此,當當前步數 h n 最大可走步數時,就可以剪枝...