1. 程式人生 > >中北大學NUC2017新生賽1003/NOJ-1983

中北大學NUC2017新生賽1003/NOJ-1983

題意:

一個愉快的週末

時間限制: 1000ms 記憶體限制: 65535KB

通過次數: 13 總提交次數: 56

問題描述

大家都知道,AiR_H和zbt是好朋友。AiR_H十分喜歡研究歷史,這週末他想去山西一個神祕的地方來學習山西的歷史,便想拉上zbt一起去。AiR_H對zbt說:山西,因居太行山之西而得名,簡稱“晉”,東依太行山,西、南依呂梁山、黃河,北依長城,與河北、河南、陝西、內蒙古等省區為界。介於北緯34°34′—40°44′,東經110°14′—114°33′之間,總面積15.67萬平方千米…………zbt一臉懵逼,表示,我去,我去還不行嗎。他們來到這個無人管理但是有一套自動開門鎖門系統神祕的高樓。正在他們在最高樓觀光的時候,發現,還有五分鐘就要鎖門了。被鎖住出不去沒飯吃餓死的話他們就要變成歷史啦!!!zbt十分驚恐,把這棟樓的地圖交給AiR_H,讓演算法大神AiR_H寫個程式估計夠不夠時間。但是AiR_H此時很慌,所以打電話求助你讓你幫他算一算至少需要多少時間才能出去。

輸入描述

第一行輸入一個整數n,代表這棟樓有多少層。AiR_H和zbt就在最高層。(1 <= n <= 100)

下面依次有n個地圖(大小都為5 * 5),第i個地圖表示第i樓的物品擺放情況

1樓的物品擺放情況

2樓的物品擺放情況

………………

n樓的物品擺放情況

說明書:

'.'代表可以行走的地方

'#'代表障礙物

'@'代表樓梯

1樓'd'字元代表出口

n樓'a'字元代表AiR_H和zbt的位置

相鄰兩層樓至少有一個樓梯是相同位置的,代表可以從這個位置上樓或者下樓

每個樓梯只能連線x ~ x+1樓或x ~ x-1樓

移動一格算1步,下樓梯算1步

AiR_H和zbt移動的速度為1步/秒

輸入保證至少有一條可以出去的通道。

輸出描述

輸出一個數字代表AiR_H和zbt離開大樓至少需要多少秒。

樣例輸入
3
[email protected]#.
#.#..
#...d
#.#..
..##.

[email protected]
#.#.#
#...#
##.##
@....

.....
...#.
..a#.
####.
@....
樣例輸出
28

思路:比賽一開始就發現了這個非常像kuangbin搜尋1裡面的BFS,興奮的一頓亂敲最後只得了10分,心態直接炸穿。

描述裡有一句話:

“相鄰兩層樓至少有一個樓梯是相同位置的,代表可以從這個位置上樓或者下樓。每個樓梯只能連線x ~ x+1樓或x ~ x-1樓。”

     意思就是樓梯只能連線2層,不能連線3層及以上的樓層。則在搜尋的時候,若從第i層走樓梯到了第j層,那麼第j層的那個對應的樓梯字元要從‘@’變為‘.’。

此意為i到j層為樓梯,j層的這個位置的樓梯就不會到別的層了。

    搜尋的順序是先列舉一層的四個方向,若當前為樓梯,再列舉上下方向。

坑點:絕對想不到的WA點:輸入!!!我把ios::sync_with_stdio(false);刪掉就A了,鵬飛把getchar();刪了就A了。(他的原因是noj目前不支援getcha

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<stack>

typedef long long ll;

using namespace std;

int n;

char mapp[110][10][10];

bool vis[110][10][10];

struct node{
	int c;
	int x;
	int y;
	int step;
};

int sc,sx,sy;
int ec,ex,ey;

int dir1x[] = {0, -1, 0, 1}, dy[] = {1, 0, -1, 0};

int dir2[] = {-1, 1};

bool check(int x,int y,int z){
	if(y >= 0 && y < 5 && z >= 0 && z < 5 && mapp[x][y][z]!='#'&&!vis[x][y][z]) 
		return true;
	return false;
}

int bfs(){
	queue<node> Q;
	node a;
	node nxt;
	
	a.c = n-1 ,  a.x = sx  , a.y = sy;
	a.step = 0;

	vis[n-1][sx][sy] = 1;
	Q.push(a);
	
	while (!Q.empty()){
		a = Q.front();
		Q.pop();
		//cout<<a.c<<a.x<<a.y<<endl;
		if(a.c == 0 && a.x == ex && a.y == ey){
			return a.step;
		}
		for(int i = 0 ; i<4 ; i++){
			nxt.c = a.c;
			nxt.x = a.x+dir1x[i];
			nxt.y = a.y+dy[i];
			
			if(check(nxt.c , nxt.x , nxt.y)){
				vis[nxt.c][nxt.x][nxt.y] = 1;
            	nxt.step = a.step+1;
            	Q.push(nxt);
			}
		}
		
		
		if(mapp[a.c][a.x][a.y] == '@'){
			for(int i = 0 ; i<2 ; i++){
				nxt.c = a.c+dir2[i];
				nxt.x = a.x;
				nxt.y = a.y;
				if(nxt.c>=0 && nxt.c<n && !vis[nxt.c][nxt.x][nxt.y] && mapp[nxt.c][nxt.x][nxt.y]=='@'){
					mapp[nxt.c][nxt.x][nxt.y] = '.';
					vis[nxt.c][nxt.x][nxt.y] = 1;
					nxt.step = a.step+1;
					Q.push(nxt);
				}
			}
		}
	}
	return -1;
}

int main(){
	cin>>n;
	for(int i = 0 ; i<n ; i++){
		for(int j = 0 ; j<5; j++){
			scanf("%s",mapp[i][j]);
		}
	}
	for(int i = 0; i < 5; i++){
		for(int  j = 0; j < 5; j++){
			if(mapp[n-1][i][j] == 'a'){
					sx = i;
					sy = j;	
				}
				if(mapp[0][i][j] == 'd'){
					ex = i;
					ey = j;
				}
		}
	}
	printf("%d\n",bfs());
	return 0;
}