【2011.10.29模擬】迷宮題解

題目描述

北京地圖可以看作是R*C的網格,奧運會期間對有的地方要進行交通管制,有的地方不允許進入,有的地方對離開時的行駛方向有限制:有的只允許走到上下兩個相鄰的格子,有的只允許走到左右兩個相鄰的格子,沒有的任何限制的地方上下左右四個方向都允許。

現在給你地圖的描述,格子的描述如下:
● “+”表示可以向任意方向(上、下、左、右)移動一格;
● “-”表示只能向左右方向移動一格;
● “|”表示只能向上下方向移動一格;
● “*”表示該位置不能到達。

你的任務是計算出從左上角到右下角的最少需要經過的格子數。

輸入
輸入第一行一個整數t(1<=t=10)表示有t組測試數據。
每一個測試數據,第一行一個整數r,第二行一個整數c(1<=r,c<=100)表示地圖是r行c列的,接下來r行,每行c個字符,每個字符是{+,,-,|}中的一種。你可以假設左上角不會是“”。

輸出
輸出有t行,每行一個整數表示對應測試數據所需的最少格子數,如果到達不了右下角輸出-1。

樣例輸入
3
2
2
-|
+
3
5
+||
+
+++|+
**–+
2
3
++
+
+

樣例輸出
3
7
-1

數據範圍限制

提示
50% 1<=r,c<=20
100% 1<=r,c<=1000

難度:⭐⭐⭐

方法:記憶化搜索(BFS)

實際分數:90.9

方法1:DFS

這個就沒什麼好說的了
DFS直接暴力就行,預計分數40~80不等,不是滿分的方法這裏就先跳過辣

方法2:正解BFS

首先我們來分析一下這一題,
這一題每個點走的方法都不大一樣,跟我們平時做的那些四向擴展的題不同,
所以步驟可能較繁瑣,很多童鞋就是這樣懵逼

在這裏插入圖片描述
步驟雖然繁瑣,但是也很好做,只要學過 BFS這題也就還好吧…
四個不同的符號:

* 直接跳過(這說法不準確,因爲“*”就是障礙,壓根去不了這點)
1 上下走
- 左右走
+ 怎麼走都行

代碼很長,但是爲什麼好做呢?
因爲我們有祕密武器:ctrl+c
這題基本就完事兒了,你也許會問我:如此簡單汝爲何一開始會錯?
我只能告訴你:我用錯了memset…

在這裏插入圖片描述
不知爲什麼,我用的memset沒用…

題外話:也許是我沒用

在這裏插入圖片描述
走開走開…
好,疑問又來了:爲什麼汝改出來了還是90.9?
呵,呵呵
因爲忘記特判了…

if(r==1&&c==1)//咋辦?

printf("1");  //就是這錯QAQ...

. . . . . . . . . . . . . . . . . . . . . . . . .酷 的. . . . . . . . . . . . . . . . . . . . . . . . .

//已加防抄襲辣
#include<iostream>
using namespace std;
int t,r,c,book[1005][1005],p[1000005][3];
int dx[5]={0,1,-1,0,0};
int dy[5]={0,0,0,1,-1};
char str[1005][1005];
int mian(){
	in(t);
	//讀入
	for(int i=1;i<=t;i++){
		in(r,c);
		if(r==1&&c==1) ...
		int flag=0;
		for(int j=0;j<r;j++)
			cin>>str[j];
		int h=0,t=1;
		memset(book,0,sizeof(0));
		memset(p,0,sizeof(0));
		book[0][0]=1;
		p[1][0]=p[1][1]=0;
		p[1][2]=1;
		while (h<t){
			h++;
			//幾種符號的遍歷方法
			if(str[p[h][1]][p[h][0]]=='+'){
				for(int i=1;i<=4;i++){
					int xx=p[h][0]+dx[i];
					int yy=p[h][1]+dy[i];
					if(xx>=0&&xx<r&&yy>=0&&yy<c&&str[xx][yy]!='*'&&book[xx][yy]==0){
						t++;
						book[xx][yy]=1;
						p[t][0]=xx;
						p[t][1]=yy;
						p[t][2]=p[h][2]+1;
						if(xx==r-1&&yy==c-1){
							printf("%d\n",p[t][2]);
							flag=1;
							break;
						}
					}
				}
				if(flag==1) break;
			}
			if(str[p[h][1]][p[h][0]]=='|'){
				for(int i=1;i<=2;i++){
					int xx=p[h][0]+dx[i];
					int yy=p[h][1]+dy[i];
					if(xx>=0&&xx<r&&yy>=0&&yy<c&&str[xx][yy]!='*'&&book[xx][yy]==0){
						t++;
						book[xx][yy]=1;
						p[t][0]=xx;
						p[t][1]=yy;
						p[t][2]=p[h][2]+1;
						if(xx==r-1&&yy==c-1){
							printf("%d\n",p[t][2]);
							flag=1;
							break;
						}
					}
				}
				if(flag==1) break;
			}
			if(str[p[h][1]][p[h][0]]=='-'){
				for(int i=3;i<=4;i++){
					int xx=p[h][0]+dx[i];
					int yy=p[h][1]+dy[i];
					if(xx>=0&&xx<r&&yy>=0&&yy<c&&str[xx][yy]!='*'&&book[xx][yy]==0){
						t++;
						book[xx][yy]=1;
						p[t][0]=xx;
						p[t][1]=yy;
						p[t][2]=p[h][2]+1;
						if(xx==r-1&&yy==c-1){
							printf("%d\n",p[t][2]);
							flag=1;
							break;
						}
					}
				}
				if(flag==1) break;
			}
		}
		if(flag==0) printf("-1\n");
	}
	return 0;
}```
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章