DFS 剪枝 BFS 鳴人和佐助

2021-10-04 01:25:32 字數 3357 閱讀 9271

佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?

已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左右四個方向移動,每移動乙個距離需要花費1個單位時間,打敗大蛇丸的手下不需要時間。如果鳴人查克拉消耗完了,則只可以走到沒有大蛇丸手下的位置,不可以再移動到有大蛇丸手下的位置。佐助在此期間不移動,大蛇丸的手下也不移動。請問,鳴人要追上佐助最少需要花費多少時間?

輸入的第一行包含三個整數:m,n,t。代表m行n列的地圖和鳴人初始的查克拉數量t。0 < m,n < 200,0 ≤ t < 10

後面是m行n列的地圖,其中@代表鳴人,+代表佐助。*代表通路,#代表大蛇丸的手下。

輸出包含乙個整數r,代表鳴人追上佐助最少需要花費的時間。如果鳴人無法追上佐助,則輸出-1。

樣例輸入

樣例輸入1

441

#@##

**##

###+**

**

樣例輸入2

442

#@##

**##

###+**

**

樣例輸出

樣例輸出1

6樣例輸出2

4dfs+剪枝

dfs:

首先dfs鳴人的點,再接著dfs鳴人四周的各點;

終止條件——查克拉<0

最優性剪枝:

*剪枝1:*建立三維陣列sep,初始值設定為最大值,將當前x,y,查克拉所費的時間數(temptime)儲存至sep[x][y][查克拉],若再次來到該點x,y且擁有相同的查克拉,而時間數更大的話,那此次dfs的總時間數必將大於前者,即不可能為最少時間——遺棄之。

*剪枝2:*當前所用時間大於最快的總時間——遺棄之。

#include

#include

using

namespace std;

int time;

//找到佐助的最少時間

int temptime;

//過程中的時間數,每次dfs前歸零

int m,n,t;

//m為行數,n為列數,t為查克拉數

char map[

210]

[210];

//儲存地圖

int narotox;

//鳴人的初始行

int narotoy;

//鳴人的初始列

int visited[

210]

[210];

//初始為0,當此遍歷時走過則標記為1,防止重複走同乙個點.

int lx[4]

=;//下乙個行數的遍歷陣列

int ly[4]

=;//下乙個列數的遍歷陣列

int x1,y1;

int sep[

210]

[210][

12];//三維陣列————為最優性剪枝用

void

dfs(

int x,

int y,

int chakora)

visited[x]

[y]=1;

//標記為已訪問

temptime++

;//時間+上

for(

int i=

0;i<

4;i++

) visited[x]

[y]=0;

//都遍歷完成——返回上層並將此點標記為未訪問

temptime--

;//訪問這個點用的時間也剪掉

}int

main()

}//儲存鳴人的位置

memset

(sep,

0x3f

,sizeof sep)

;//初始化sep為極大值

//關於為什麼要賦值為0x3f↓

// time=

1<<30;

temptime=0;

//初始化temptime

dfs(narotox,narotoy,t);if

(time==

1<<

30) cout<<

"-1"

<

else cout<

}return0;

}

bfs演算法找到的第乙個解一定是最短解,無需像dfs一樣考慮剪枝

#include

#include

#include

using

namespace std;

//關鍵思路:狀態比位置多一維,即處於該位置時的查克拉數目

//無需剪枝——找最優解比dfs方便

int m,n,t;

char map[

220]

[220];

int nx,ny;

int dp[4]

[2]=

,,,}

;int x1,y1;

int flag;

struct nrt

//初始化結構函式,方便轉移};

//建立佇列,存放頭節點

int visited[

220]

[220][

15];//訪問過的xy 是三位陣列——還包括查克拉數 !!!有三個狀態)——三維陣列!很關鍵

intmain()

}//找最少時間,用bfs更好

//設定起始位置

memset

(visited,0,

sizeof visited)

; f.

push

(nrt

(nx,ny,

0,t));

//鳴人入隊

visited[nx]

[ny]

[t]=1;

while

(!f.

empty()

)if(map[x1]

[y1]

=='#'

&&s.c>0)

if(map[x1]

[y1]

=='*')}

f.pop();

if(flag==1)

}if(flag==0)

}return0;

}

鳴人和佐助

已知一張地圖 以二維矩陣的形式表示 以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左右四個方向移動,每移動乙個距離需要花費1個單位時間,打敗...

計蒜客 鳴人和佐助 bfs

佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?已知一張地圖 以二維矩陣的形式表示 以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左右四個...

003 鳴人和佐助

描述 佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?已知一張地圖 以二維矩陣的形式表示 以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左...