1. 程式人生 > >[題解] [BFS] [無AC代碼僅講解] CodeForces Gym 101755 H. Safe Path

[題解] [BFS] [無AC代碼僅講解] CodeForces Gym 101755 H. Safe Path

如果 play 輸出 ide ++ sign put 多少 ack

VJudge題目:https://cn.vjudge.net/contest/279018#problem/K

CodeForces Gym 101755 H. Safe Path http://codeforces.com/gym/101755/problem/H


關於DFS連通塊的題解:https://www.cnblogs.com/Kaidora/p/10392641.html

關於BFS求數字的題解:https://www.cnblogs.com/Kaidora/p/10392293.html


為什麽不提供

AC代碼,因為我的BFS提交上去Runtime error on test 5

而我寫的暴力都能到test 14才超時,實在不想再重寫了,再見。


如果你做過連通塊字符畫的題目,那麽這道題應該不難。


先說明題意:

輸入一個nm列的字符畫,其中有起點S,終點F,怪物M,空地 .

輸入提供了怪物走動的步數。如果怪物能到達的位置視為不可通過,包括起始點。


現在問起點到終點需要多少步。


輸入輸出:

輸入n m d 代表 行 列 怪物步數 (2?≤?n*m?≤?20,0000,?0?≤?d?≤?20,0000

輸入n*m字符畫

輸出步數

示例:

Input

5 7 1
S.M...M
.......
.......
M...M..
......F

Output

12

Input

7 6 2
S.....
...M..
......
.....M
......
M.....
.....F

Output

11

Input

7 6 2
S.....
...M..
......
......
.....M
M.....
.....F

Output

-1

Input

4 4 2
M...
.S..
....
...F 

Output

-1

n*m=20,0000而不是n=m=20,000char map[200002][200002]是開不了的。

讀入nm後再建立map[n+2][m+2]則可以通過編譯。(請勿模仿!)


然後初始化,輸入。


先不要管起始點,把怪能到達的地方找出來。


結構體有三個成員xystep

xy是坐標,step是當前步數。


首先把字符畫中的M的坐標和步數0加入結構體隊列。


寫一個bfsMonster()

從隊列中取走一個結構體,得到坐標xy,步數step。步數step==d則拋棄數據重新在隊列取結構體;(step==d表明這一格是最大步數了)

否則檢查地圖中相鄰的四格。如果這格非\0且不是M,就把字符刷為M,同時把這一格的坐標和步數step+1加入隊列。


隊列處理完你可以把地圖輸出,看看地圖中的M是不是擴散開的樣子。如第一例:

SMMM.MM
..M...M
M...M..
MM.MMM.
M...M.F

再暴力搜索SF,記下坐標。沒有搜到表明被怪覆蓋了,可以直接輸出-1


S的坐標和步數0加入隊列,寫一個bfsPlayer()

進行與bfsMonster類似的操作,不過去掉step==d的檢查,改為坐標值檢查。

如果當前坐標x+yF的坐標Fx+Fy只相差1,說明你搜到終點旁,可以輸出step+1了。

隊列處理完依然沒有搜到終點,說明終點被怪隔開了,輸出-1


刷經過的路徑是必須要的,這樣可以防止重復搜索。如第一例:

SMMMPMM
PPMPPPM
MPPPMPP
MMPMMMP
MPPPM.F

附代碼參考。再次說明這個代碼會Runtime error,可能是map數組與結構體隊列太大爆掉的。希望這個代碼能啟發你。

(那四行整齊難看的代碼是新手早期作品,我懶得改,復制到0.3版還在用233

技術分享圖片
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 /*
  5 //結構體隊列實現
  6 struct NodeQueue
  7 {
  8     short exist;
  9     int x,y,step;
 10     struct NodeQueue *next;
 11 }head={0,0,0,0,0};
 12 struct NodeQueue *front=&head;
 13 struct NodeQueue *back=&head;
 14 struct NodeQueue *p=0;
 15 struct NodeQueue* push(int x,int y,int step)
 16 {
 17     back->next=malloc( sizeof(struct NodeQueue) );
 18     back=back->next;
 19     back->exist=1;
 20     back->x=x,back->y=y,back->step=step;
 21     back->next=0;
 22     if(front==&head)
 23     {
 24         front=back;
 25         head.next=0;
 26     }
 27     return back;
 28 }
 29 struct NodeQueue* pull()
 30 {
 31     if(front!=back)
 32     {
 33         struct NodeQueue *p;
 34         p=front->next;
 35         free(front);
 36         front=p;
 37         
 38     }
 39     else if(front!=&head)
 40     {
 41         front=&head;
 42         free(back);
 43         back=front;
 44     }
 45     return front;
 46 }
 47 //over
 48 */
 49 struct Node
 50 {
 51     short exist;
 52     int x,y,step;
 53 }que[200002]={{0,0,0,0}};
 54 struct Node *front=&que[0];
 55 struct Node *back=&que[0];
 56 void push(int x,int y,int step)
 57 {
 58     back++;
 59     back->exist=1;
 60     back->x=x,back->y=y,back->step=step;
 61     if(front==&que[0])
 62     {
 63         front=back;
 64     }
 65 }
 66 void pull()
 67 {
 68     if(front==back)
 69     {
 70         front=&que[0];
 71         back=front;
 72     }
 73     else
 74     {
 75         front++;
 76     }
 77 }
 78 
 79 int N,M,D;
 80 int Sx=0,Sy=0,Fx=0,Fy=0;
 81 int main()
 82 {
 83     scanf("%d%d%d",&N,&M,&D);        getchar();
 84     char map[N+2][M+2];                memset(map,0,(N+2)*(M+2)*sizeof(char) );
 85     
 86     for(int n=1;n<=N;n++)
 87     {
 88         gets( &map[n][1] );
 89         for(int m=1;m<=M;m++)
 90         {
 91             if( map[n][m]==M )
 92             {
 93                 push(n,m,0);
 94             }
 95         }
 96     }
 97     //輸入並完成‘M‘入隊
 98     
 99     int Monster(int x,int y,int step,char map[N+2][M+2]);
100     for(;;)
101     {
102         Monster(front->x,front->y,front->step,map);
103         pull();
104         if(back->exist==0)break;
105     }
106     //將地圖上怪能到達的點塗為怪
107     
108 //    for(unsigned n=1;n<=N;n++)
109 //        puts( &map[n][1] );
110     
111     for(int n=1;n<=N;n++)
112         for(int m=1;m<=M;m++)
113         {
114             if( map[n][m]==S )    Sx=n,Sy=m;
115             if( map[n][m]==F )    Fx=n,Fy=m;
116         }
117     //找到起始點
118     
119     int player(int x,int y,int step,char map[N+2][M+2]);
120     if( Sx && Sy && Fx && Fy )
121     {
122         push(Sx,Sy,0);
123         while(1)
124         {
125             if( player(front->x,front->y,front->step,map) )
126                 return 0;
127             pull();if(back->exist==0)break;
128         }
129     }
130     //刷路徑直到找到F
131     
132 //    for(unsigned n=1;n<=N;n++)
133 //        puts( &map[n][1] );
134     
135     puts("-1");
136     return 0;
137 }
138 
139 int Monster(int x,int y,int step,char map[N+2][M+2])
140 {
141     if( step==D )return 0;
142     if( map[x-1][y]!=M && map[x-1][y]){    map[x-1][y]=M;    push(x-1,y,step+1);    }
143     if( map[x+1][y]!=M && map[x+1][y]){    map[x+1][y]=M;    push(x+1,y,step+1);    }
144     if( map[x][y-1]!=M && map[x][y-1]){    map[x][y-1]=M;    push(x,y-1,step+1);    }
145     if( map[x][y+1]!=M && map[x][y+1]){    map[x][y+1]=M;    push(x,y+1,step+1);    }
146     return 0;
147 }
148 
149 int player(int x,int y,int step,char map[N+2][M+2])
150 {
151     if( (x==Fx || y==Fy) && (x+y==Fx+Fy-1 || x+y==Fx+Fy+1) ){    printf("%d\n",step+1);    return 1;    }
152     if( map[x-1][y]==. ){    map[x-1][y]=P;    push(x-1,y,step+1);    }
153     if( map[x+1][y]==. ){    map[x+1][y]=P;    push(x+1,y,step+1);    }
154     if( map[x][y-1]==. ){    map[x][y-1]=P;    push(x,y-1,step+1);    }
155     if( map[x][y+1]==. ){    map[x][y+1]=P;    push(x,y+1,step+1);    }
156     return 0;
157 }
158 /*
159 int QueueAll()
160 {
161     struct NodeQueue *p=front;
162     if(p->exist==0)return 0;
163     while(1)
164     {
165         printf("%d,%d,%d\n",p->x,p->y,p->step);
166         p=p->next;
167         if(p==0)return 0;
168     }
169     p=0;
170 }
171 */
View Code

[題解] [BFS] [無AC代碼僅講解] CodeForces Gym 101755 H. Safe Path