鳴人和佐助(含特殊的狀態的BFS)
阿新 • • 發佈:2019-01-24
024:鳴人和佐助
總時間限制:
1000ms
記憶體限制:
65536kB
描述
佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?
已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每一個單位的查克拉可以打敗一個大蛇丸的手下。假設鳴人可以往上下左右四個方向移動,每移動一個距離需要花費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
分析:這題的話要注意的點是查卡拉也vis(判斷該路徑有沒有走過的一個狀態)。
#include <stdio.h> #include <iostream> #include <queue> using namespace std; struct Node{ int r,c;//所在行和列 int t;//查克拉的量 int level;//所在的步數 }; char map[210][210]; int vis[210][210][15]={0};//這題中影響路徑的還有查克拉的狀態 int M,N,T; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int main() { int i,j; int r1,c1;//鳴人位置 int r2,c2;//佐助位置 scanf("%d %d %d",&M,&N,&T); for(i=0;i<M;i++){ for(j=0;j<N;j++){ cin>>map[i][j]; if(map[i][j]=='@'){ r1=i; c1=j; } if(map[i][j]=='+'){ r2=i; c2=j; } } } vis[r1][c1][T]=1;//初始位置 queue<struct Node> q;//佇列為結構體型別的佇列 Node node; node.r=r1; node.c=c1; node.level=0; node.t=T; q.push(node); while(!q.empty()){ Node temp=q.front(); q.pop(); if(temp.r==r2&&temp.c==c2){ printf("%d\n",temp.level); return 0; } for(i=0;i<4;i++){ Node temp2; temp2.r=temp.r+dir[i][0]; temp2.c=temp.c+dir[i][1]; if(temp2.r>=0&&temp2.r<M&&temp2.c>=0&&temp2.c<N){//不越界 if(map[temp2.r][temp2.c]=='#'&&temp.t>=1&&vis[temp2.r][temp2.c][temp.t-1]==0){//很容易寫錯成vis[temp2.r][temp2.c][temp2.t-1]==0,但注意之前並沒有給temp2.t賦值 temp2.t=temp.t-1;//遇見大蛇丸部下的情況 temp2.level=temp.level+1; q.push(temp2); vis[temp2.r][temp2.c][temp2.t]=1; } else if(map[temp2.r][temp2.c]!='#'&&vis[temp2.r][temp2.c][temp.t]==0){//很容易寫錯成vis[temp2.r][temp2.c][temp2.t]==0,但注意之前並沒有給temp2.t賦值 temp2.t=temp.t;//沒遇到大蛇丸部下 temp2.level=temp.level+1; q.push(temp2); vis[temp2.r][temp2.c][temp2.t]=1; } } } } cout<<-1<<endl; return 0; }