2.思路分析
3.注意點
4.ac**
5.總結
佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?
已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左右四個方向移動,每移動乙個距離需要花費1個單位時間,打敗大蛇丸的手下不需要時間。如果鳴人查克拉消耗完了,則只可以走到沒有大蛇丸手下的位置,不可以再移動到有大蛇丸手下的位置。佐助在此期間不移動,大蛇丸的手下也不移動。請問,鳴人要追上佐助最少需要花費多少時間?
輸入的第一行包含三個整數:m,n,t。代表m行n列的地圖和鳴人初始的查克拉數量t。0 < m,n < 200,0 ≤ t < 10
後面是m行n列的地圖,其中@代表鳴人,+代表佐助。*代表通路,#代表大蛇丸的手下。
輸出包含乙個整數r,代表鳴人追上佐助最少需要花費的時間。如果鳴人無法追上佐助,則輸出-1。
樣例輸入1
4 4 1
#@##
**##
###+
****
樣例輸入2
4 4 2
#@##
**##
###+
****
樣例輸出1
6樣例輸出2
4
原題鏈結.
根據本題描述與輸入,題目是一道有條件限制的迷宮最短路徑搜尋問題。鳴人的行走步長始終為1,且迷宮中節點間距離全部相等;如果沒有查克拉的限制完全可以使用bfs演算法求解(甚至直接橫縱座標作差求和)。
根據bfs的性值,先擴充套件出的節點必然距離更短->花費時間更短;但由於本題的查克拉限制,到達同一節點花費時間更短的路徑未必能成功營救佐助(可能經歷了很多大蛇丸手下,後面有大蛇丸手下的路徑就無法通過了)。鳴人的狀態可以用乙個四元組表示,即(x座標,y座標,查克拉量,當前時間);這裡利用結構體實現。如果在查克拉限制的前提下最終能擴充套件出佐助所在節點則問題有解且第一次擴充套件到佐助的情況即為最優解。
利用2.2中給出的方法能通過此題,鳴人多條路徑的不同狀態:(x,y,查克拉,當前時間)都會被擴充套件到,時空複雜度較高;我們對其進一步分析提前剪掉一些無用的分枝。在bfs中,同一節點如果在後面擴充套件出的節點如果查克拉量如果比之前擴充套件出節點的查克拉量更高則有必要擴充套件;反之則沒有必要擴充套件。因此,我們可以為迷宮矩陣元素多新增乙個引數即當前節點最先被擴充套件時的查克拉量。
由於查克拉限制的影響,本題中迷宮的每個格點其實可以經歷2次或以上;不能強行套用每個節點只遍歷一次的**模板。
個人感覺本題難點在於鳴人狀態的表示以及剪枝,**實現難度不大。
本題中為了練習自行實現資料結構,使用了自定義的佇列;其實完全可以使用stl。
分析思路與注意點後,貼出思路對應的ac**。
#include
using
namespace std;
int m,n,t;
int a;
struct node
;struct point
;int x_start,y_start,x_end,y_end;
node maze[
201]
[201];
class
queue
bool
empty()
void
enqueue
(int x,
int y,
int time,
int t,
int parent=-1
)void
enqueue
(point p)
point dequeue()
intfront_time()
};void
init()
else
if(maze[i]
[j].c ==
'+')}}
for(
int i=
0;i<=m+1;
++i)
for(
int j=
0;j<=n+1;
++j)
}void
out_put()
cout<
queue q;
intmaze_naruto()
if(maze[p.x -1]
[p.y]
.c ==
'#')
}else}if
(maze[p.x +1]
[p.y]
.c ==
'#')
}else}if
(maze[p.x]
[p.y -1]
.c ==
'#')
}else}if
(maze[p.x]
[p.y +1]
.c ==
'#')
}else}}
return-1
;}intmain()
通過本題的練習對於bfs的理解有所深化,一味地套用解題模板遇到這題是真的會碰釘子。「狀態空間」的設計也是需要我們重點考慮的,為什麼像平時那樣開乙個visit陣列(判重陣列)每個節點遍歷一次就ok的套路不適用了;因為本題有查克拉的限制,走到同乙個節點但是查克拉不同其實是算作兩個狀態;從狀態空間遍歷這一角度思考,本題只是visit陣列變複雜了;常規問題是(x座標,y座標)本題是(x座標,y座標,查克拉)本質上還是一樣的。最後,由於狀態空間變得複雜了,對其遍歷過程進行化簡就是非常重要的;剪枝實際上就是去掉了一些無用的狀態遍歷。
使用了比較*****的寫法,**有些冗餘;後期可能會結合胡凡老師演算法筆記中的一些模板寫法進行優化。不過執行效率我還是比較滿意的,百練上面是20ms。
鳴人和佐助
已知一張地圖 以二維矩陣的形式表示 以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左右四個方向移動,每移動乙個距離需要花費1個單位時間,打敗...
003 鳴人和佐助
描述 佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?已知一張地圖 以二維矩陣的形式表示 以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左...
4115 鳴人和佐助
總時間限制 1000ms 記憶體限制 65536kb 描述佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?已知一張地圖 以二維矩陣的形式表示 以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的...