1. 程式人生 > >Openjudge-4115-佐助和鳴人

Openjudge-4115-佐助和鳴人

這一題是一道廣搜的題目,首先我們通過讀入字串讀入每一行,然後順帶找到鳴人的位置。

然後我們初始化之後,就進行廣搜,還是廣搜的格式,但是要壓入佇列的條件我們可以稍微變一變,我們可以直接判斷下一個要走的點,是星號或者是加號,我們就判斷是否走過這一點是否走過。

我們判斷的依據是,假設我們走這一點,消耗零個查克拉,然後在標記數組裡面檢視是否為零。

這麼說,你可能不明白,但是如果這一點是#號,且查克拉大於零,我們準備走這個點,然後消耗一個查克拉,然後我們就可以去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;
}