SCOI2005 騎士精神(IDA )

2022-04-30 18:24:10 字數 1235 閱讀 7311

題面:[scoi2005]騎士精神

對於這道題,我們第一眼:\(bfs\)爆搜

第二眼:發現事情沒這麼簡單:這是道省選題

第三眼:仔細一想,直接\(bfs\)難道不會被卡爆嗎??

第四眼:發現題目中有:「如果能在15步以內(包括15步)到達目標狀態,則輸出步數,否則輸出-1

好的,\(ida\)*:啟發式迭代加深

\(ida\)*是什麼?

其實就是在\(a\)*的基礎上加上迭代加深

還不知道\(a\)*的同學點這裡

迭代加深其實就是每次搜尋的時候限制你的搜尋深度,使你的搜尋樹的深度保持在乙個較為合理的地方,使你的時間不會**,這樣就可以使你在全域性搜尋的深度很大而答案深度很小的情況下(也是使用\(ida\)*的條件)快速得出答案

在這道題中,明顯可以看出,答案深度\(<=15\),所以我們考慮使用\(ida\)*,在每次搜尋是加上限制深度條件\(maxstep\),如果當前搜尋深度\(step==maxstep\),就返回答案

作為\(a\)*的精髓,估價函式\(g(x)\)當然是我們思考的主要物件

我們可以發現,這道題給出了棋盤的目標布局

我們可以每次\(dfs\)將要進入下一層時,我們都對下一層的棋盤和目標棋盤進行對比,如果差異值\(tot+step>maxstep\),那麼我們就不進入下一層

詳見**

#includeusing namespace std;

const int nextx[8]=;

const int nexty[8]=;

//目標棋盤

int goal[7][7]=,

, ,, , };

char ch[6][6];

int num[6][6];

bool flag=0;

int diff()//差異值

} return tot;

}bool check(int x,int y)

void dfs(int step,int x,int y,int maxstep)

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

int main()

} for(int i=1;i<=15;i++)

}if(!flag)puts("-1");

} return 0;

}

SCOI2005 騎士精神 IDA

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

SCOI2005 騎士精神

乙個比較直接的思路是bfs爆搜,但這樣只能拿20分,所以考慮優化。在測試樣例時能夠看到深度為7的時候很快就跑出來了,在結合本題最大深度是15,所以可以用雙向bfs來優化,即從兩邊各跑7或8的深度,最後用map合併,有點類似折半搜尋。另外有一些需要注意的小細節已經在 中注釋。code include ...

SCOI2005 騎士精神

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