抓住那頭牛 POJ NO 2971

2021-08-07 06:01:19 字數 2032 閱讀 8541

總時間限制: 2000ms

記憶體限制: 65536kb

描述

農夫知道一頭牛的位置,想要抓住它。農夫和牛都位於數軸上,農夫起始位於點n(0<=n<=100000),牛位於點k(0<=k<=100000)。農夫有兩種移動方式:

從x移動到x-1或x+1,每次移動花費一分鐘

從x移動到2*x,每次移動花費一分鐘

假設牛沒有意識到農夫的行動,站在原地不動。農夫最少要花多少時間才能抓住牛?

輸入 兩個整數,n和k

輸出 乙個整數,農夫抓到牛所要花費的最小分鐘數

樣例輸入

5 17

樣例輸出

寬度優先搜尋(bfs,breadth-first search)按照距開始狀態由遠及近的順序進行搜尋,因此可以很容易用來求最短路徑,最少操作之類的問題。它與深度優先搜尋類似,從某個狀態出發搜尋所有可以到達的狀態。對於同乙個狀態,寬度優先搜尋只經過一次,因此複雜度為o(

狀態數∗

轉移方式

) 在這個問題中,狀態僅僅是目標目前所在的位置座標,因此可以構造成in

t 來表示狀態。當狀態更加複雜時,就需要用pa

ir或者封裝成乙個類來表示狀態了。

在這裡結合學步園 的與樣例輸入說明bfs在此題的使用。

有兩點需要說明:

1. 注意紅色的叉,在搜尋過程中可能產生已經搜尋過的節點,這時要跳過。

2. 已經搜尋過第i層的節點,那麼第i+

1 層的搜尋從哪個節點開始?這時需要設定乙個佇列,

i 層已經搜尋過的節點入隊(在對第i−

1層的節點分叉時),然後依次作為第i+

1 層節點的父節點出隊。

因為要向三個狀態發生轉移,所以我們用d[

i]陣列來表示三個狀態的方向向量,這樣通過乙個迴圈就可以實現三個狀態的遍歷。

深度優先搜尋(隱式地)利用了棧進行計算,而寬度優先搜尋則利用了佇列。搜尋時首先將初始狀態新增到佇列裡,此後從佇列的最前端不斷取狀態,把從該狀態可以轉移到的狀態中尚未訪問的部分加入佇列,如此往復,直至佇列被取空或者找到了問題的解。

寬度優先搜尋與深度優先搜尋一樣,都會生成所有能遍歷到的狀態,因此需要對所有狀態進行處理時使用寬度優先搜尋也是可以的。但是遞迴函式可以很簡短地編寫,而且狀態的管理也更簡單,所以大多數情況下還是使用深度優先搜尋實現。反之,在求最短路時,深度優先搜尋需要反覆講過相同的狀態,所以此時還是使用寬度優先搜尋比較好。

寬度優先搜尋會把狀態逐個加入佇列,因此通常需要與狀態數成正比的記憶體空間。深度優先搜尋是與最大的遞迴深度成正比的,一般與狀態數相比,遞迴的深度不會太大,所以可以認為深度優先搜尋更加節省空間。

@ [email protected]

//environment:dev-c++ 5.7.1

// author: florence

// created time: 2017-08-21 20:57:48

#include

#include

#include

#define max_n 100001

using

namespace

std;

int n,k,cur,res;

int closed[max_n],d[3];//closed陣列儲存最小分鐘數,且標記已經訪問

queue

open;

void bfs()}}

res = closed[k];

cout

<< res << endl;

}int main(int argc, char** argv)

此題作為bfs的經典題型,思想值得借鑑。

noi 2971 抓住那頭牛

總時間限制 2000ms 記憶體限制 65536kb 描述農夫知道一頭牛的位置,想要抓住它。農夫和牛都位於數軸上,農夫起始位於點n 0 n 100000 牛位於點k 0 k 100000 農夫有兩種移動方式 1 從x移動到x 1或x 1,每次移動花費一分鐘 2 從x移動到2 x,每次移動花費一分鐘 ...

openjudge 2971 抓住那頭牛 解題報告

總時間限制 2000ms 記憶體限制 65536kb 描述農夫知道一頭牛的位置,想要抓住它。農夫和牛都位於數軸上,農夫起始位於點n 0 n 100000 牛位於點k 0 k 100000 農夫有兩種移動方式 1 從x移動到x 1或x 1,每次移動花費一分鐘。2 從x移動到2 x,每次移動花費一分鐘。...

抓住那頭牛

在乙個座標軸上,農夫在n點,牛在k點 假設在整個過程中牛靜止不動 現在農夫可以 1,1,2 的步數,問抓到牛的最小步數 採用stl的queue 第一次使用。include include include using namespace std int n,k const int maxn 10000...