Openjudge-4115-佐助和鳴人
阿新 • • 發佈:2018-12-04
這一題是一道廣搜的題目,首先我們通過讀入字串讀入每一行,然後順帶找到鳴人的位置。
然後我們初始化之後,就進行廣搜,還是廣搜的格式,但是要壓入佇列的條件我們可以稍微變一變,我們可以直接判斷下一個要走的點,是星號或者是加號,我們就判斷是否走過這一點是否走過。
我們判斷的依據是,假設我們走這一點,消耗零個查克拉,然後在標記數組裡面檢視是否為零。
這麼說,你可能不明白,但是如果這一點是#號,且查克拉大於零,我們準備走這個點,然後消耗一個查克拉,然後我們就可以去visited數組裡面查詢,我們是否在剩下該數目查克拉的時候走過這一點。
如果走過那就是一唄,我們廣搜的時候不能搜尋相同的點,也就是相同的位置,相同的查克拉,說明我們已經走過,我們不能再次返回。
但是如果查克拉的數目不一樣的話,就說明,我們雖然走到了相同的位置,但是我們走的路線是不一樣的,對不對。
我們在bfs搜的時候不能搜到下一層了,然後又開始回搜上一層的點,這就叫判重。
#include <iostream> #include <cstring> #include <queue> using namespace std; const int maxn=205; int m,n,t; int visited[maxn][maxn][15]; char maze[maxn][maxn]; int d[4][2]= {{-1,0},{1,0},{0,-1},{0,1}}; struct Step { int x,y,t; int step; Step(int a,int b,int c,int d):x(a),y(b),t(c),step(d){} }; queue <Step> q; int main() { scanf("%d%d%d",&m,&n,&t); Step first(0,0,0,0); memset(visited,0,sizeof(visited)); for (int i=0;i<m;i++) { scanf("%s",maze[i]); for (int j=0;j<n;j++) { if (maze[i][j]=='@') { first.x=i,first.y=j,first.t=t,first.step=0; visited[i][j][t]=1; } } } q.push(first); while (!q.empty()) { Step cur=q.front(); q.pop(); if (maze[cur.x][cur.y]=='+') { cout<<cur.step<<endl; return 0; } for (int i=0;i<4;i++) { int dx=cur.x+d[i][0]; int dy=cur.y+d[i][1]; if (dx<0||dy<0||dx>=m||dy>=n) continue; if (maze[dx][dy]=='#'&&cur.t>0&&!visited[dx][dy][cur.t-1]) { q.push(Step(dx,dy,cur.t-1,cur.step+1)); visited[dx][dy][cur.t-1]=1; } else if (maze[dx][dy]=='+'||maze[dx][dy]=='*'&&!visited[dx][dy][cur.t]) { q.push(Step(dx,dy,cur.t,cur.step+1)); visited[dx][dy][cur.t]=1; } } } cout<<-1<<endl; return 0; }