1. 程式人生 > >【資訊學奧賽一本通】1256:獻給阿爾吉儂的花束

【資訊學奧賽一本通】1256:獻給阿爾吉儂的花束

傳送門:獻給阿爾吉儂的花束

1256:獻給阿爾吉儂的花束


時間限制: 1000 ms         記憶體限制: 65536 KB
提交數: 1696     通過數: 685 

【題目描述】

阿爾吉儂是一隻聰明又慵懶的小白鼠,它最擅長的就是走各種各樣的迷宮。今天它要挑戰一個非常大的迷宮,研究員們為了鼓勵阿爾吉儂儘快到達終點,就在終點放了一塊阿爾吉儂最喜歡的乳酪。現在研究員們想知道,如果阿爾吉儂足夠聰明,它最少需要多少時間就能吃到乳酪。

迷宮用一個R×C的字元矩陣來表示。字元S表示阿爾吉儂所在的位置,字元E表示乳酪所在的位置,字元#表示牆壁,字元.表示可以通行。阿爾吉儂在1個單位時間內可以從當前的位置走到它上下左右四個方向上的任意一個位置,但不能走出地圖邊界。

【輸入】

第一行是一個正整數T(1 ≤ T ≤ 10),表示一共有T組資料。

每一組資料的第一行包含了兩個用空格分開的正整數R和C(2 ≤ R, C ≤ 200),表示地圖是一個R×C的矩陣。

接下來的R行描述了地圖的具體內容,每一行包含了C個字元。字元含義如題目描述中所述。保證有且僅有一個S和E。

 

【輸出】

對於每一組資料,輸出阿爾吉儂吃到乳酪的最少單位時間。若阿爾吉儂無法吃到乳酪,則輸出“oop!”(只輸出引號裡面的內容,不輸出引號)。每組資料的輸出結果佔一行。

【輸入樣例】

3
3 4
.S..
###.
..E.
3 4
.S..
.E..
....
3 4
.S..
####
..E.

【輸出樣例】

5
1
oop!

 

 

阿爾吉儂:我的花束呢?

知道起點和終點的題,很明顯是寬搜題,我很細心地做,同桌問我題目,我就六親不認不說話,用寬搜能很輕鬆地得到結果,你也能改改迷宮問題(NOI)或迷宮問題(一本通),我就只改了一點,用腳指頭想想很快就做出來了,阿爾吉儂會感謝我們的(阿爾吉儂:花束!花束!說好的給我花束呢?!),下面是我的程式碼,為了照顧廣大萌新(其實我就是萌新),我沒有用queue函式之類的高階東西(我也寫不出來):

#include<bits/stdc++.h>
using namespace std;
int front,rear,r,c,dx[4]={0,1,0,-1},dy[4]={1,0,-1,0},q[100010][3],lx,ly,mx,my;
char a[210][210];
void bfs();
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>r>>c;
		for(int i=1;i<=r;i++)
			for(int j=1;j<=c;j++)
			{
				cin>>a[i][j];
				if(a[i][j]=='S')
					lx=i,ly=j;
				if(a[i][j]=='E')
					mx=i,my=j;
			}
		front=0,rear=1;
		q[rear][0]=lx,q[rear][1]=ly,q[rear][2]=0;
		a[lx][ly]=1;
		bfs();
		if(q[rear][2]>=0)
			cout<<q[rear][2]<<endl;
		else
			cout<<"oop!\n";
	}
	return 0;
}
void bfs()
{
	bool find=false;
	while(front<rear)
	{
		front++;
		for(int i=0;i<4;i++)
		{
			int xx=q[front][0]+dx[i];
			int yy=q[front][1]+dy[i];
			if(xx>=1&&xx<=r&&yy>=1&&yy<=c&&a[xx][yy]!='#')
			{
				rear++;
				q[rear][0]=xx;
				q[rear][1]=yy;
				q[rear][2]=q[front][2]+1;
				a[xx][yy]='#';
				if(xx==mx&&yy==my)
				{
					find=true;
					return;
				}
			}
		}
	}
	if(!find)
	{
		q[rear][2]=-1;
		return;
	}
}

下期題目傳送門:最少步數(大家先做著哈)