題目描述
北京地圖可以看作是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;
}```