广搜——路径寻找
Tyvj 1117 拯救ice-cream
背景
可是……停电了……
冰淇淋们躺在Ice-cream home的冰柜里,慢慢地……慢慢地……融化…………
你说,她能赶在冰淇淋融化完之前赶到Ice-cream home去吗?
描述
输入格式
输出格式
测试样例1
输入
11
10
8
......s...
..........
#ooooooo.o
#.........
#.........
#.........
#.....m...
#.........
输出
10
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 #include<vector> 7 #include<queue> 8 using namespace std; 9 struct node{ 10 int x; 11 int y; 12 int dist; 13 friend bool operator < (node a,node b){ 14 return a.dist > b.dist; 15 } 16 }; 17 priority_queue<node> q; 18 int t,x,y,startx,starty,endx,endy,map[50][50],jud[50][50]; 19 int dx[4] = {-1,0,1,0}; 20 int dy[4] = {0,-1,0,1}; 21 void input(){ 22 cin>>t>>x>>y; 23 char cmd; 24 for(int i = 1;i <= y;i++){ 25 for(int j = 1;j <= x;j++){ 26 cin>>cmd; 27 if(cmd == '.') map[i][j] = 1; 28 if(cmd == '#') map[i][j] = 2; 29 if(cmd == 'o') map[i][j] = 3; 30 if(cmd == 's'){ 31 map[i][j] = 1; 32 startx = j; 33 starty = i; 34 } 35 if(cmd == 'm'){ 36 map[i][j] = 1; 37 endx = j; 38 endy = i; 39 } 40 } 41 } 42 node tmp; 43 tmp.x = startx; 44 tmp.y = starty; 45 tmp.dist = 0; 46 q.push(tmp); 47 for(int i = 1;i <= 40;i++){ 48 for(int j = 1;j <= 40;j++){ 49 jud[i][j] = 100000000; 50 } 51 } 52 } 53 bool bfs(){ 54 node now,next; 55 int nx,ny; 56 while(!q.empty()){ 57 now = q.top(); 58 q.pop(); 59 for(int i = 0;i < 4;i++){ 60 nx = now.x + dx[i]; 61 ny = now.y + dy[i]; 62 if(nx < 1 || nx > x || ny < 1 || ny > y || map[ny][nx] == 3 ||jud[ny][nx] <= now.dist + map[ny][nx]) continue; 63 next.x = nx; 64 next.y = ny; 65 next.dist = now.dist + map[ny][nx]; 66 if(nx == endx && ny == endy){ 67 if(next.dist >= t) return false; 68 else{ 69 cout<<next.dist<<endl; 70 return true; 71 } 72 } 73 q.push(next); 74 jud[ny][nx] = next.dist; 75 } 76 } 77 } 78 int main(){ 79 input(); 80 if(!bfs()) cout<<55555<<endl; 81 return 0; 82 }
Wikioi 1026 逃跑的拉尔夫
年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置。
那个装置太旧了,以至于只能发射关于那辆车的移动路线的方向信息。
编写程序,通过使用一张小镇的地图帮助警察局找到那辆车。程序必须能表示出该车最终所有可能的位置。
小镇的地图是矩形的,上面的符号用来标明哪儿可以行车哪儿不行。“.”表示小镇上那块地方是可以行车的,而符号“X”表示此处不能行车。拉尔夫所开小车的初始位置用字符的“*”表示,且汽车能从初始位置通过。
汽车能向四个方向移动:向北(向上),向南(向下),向西(向左),向东(向右)。
拉尔夫所开小车的行动路线是通过一组给定的方向来描述的。在每个给定的方向,拉尔夫驾驶小车通过小镇上一个或更多的可行车地点。
输入文件的第一行包含两个用空格隔开的自然数R和C,1≤R≤50,1≤C≤50,分别表示小镇地图中的行数和列数。
以下的R行中每行都包含一组C个符号(“.”或“X”或“*”)用来描述地图上相应的部位。
接下来的第R+2行包含一个自然数N,1≤N≤1000,表示一组方向的长度。
接下来的N行幅行包含下述单词中的任一个:NORTH(北)、SOUTH(南)、WEST(西)和EAST(东),表示汽车移动的方向,任何两个连续的方向都不相同。
输出文件应包含用R行表示的小镇的地图(象输入文件中一样),字符“*”应该仅用来表示汽车最终可能出现的位置。
4 5
.....
.X...
...*X
X.X..
3
NORTH
WEST
SOUTH
.....
*X*..
*.*.X
X.X..
思路:
广搜模拟,位置+行驶次数判重
代码:
1 #include<stdio.h> 2 #include<iostream> 3 using namespace std; 4 5 struct node {int fa; 6 int d; 7 int x; 8 int y; 9 }f[1000000],temp; 10 11 char zxc[1010][10],s[101][101],xc; 12 int di[5]={0,0,0,-1,1}; 13 int dj[5]={0,-1,1,0,0}; 14 int head=0,tail=1,n,m,d[1010],z,g[101][101],v[60][60][1001]; 15 16 void input() 17 { int i,j,k; 18 scanf("%d %d\n",&n,&m); 19 for(i=1 ; i <= n ; i++) 20 { 21 for( j=1 ; j <= m ; j++) 22 { 23 cin>>s[i][j]; 24 if(s[i][j]=='*')f[1].x=i,f[1].y=j,s[i][j]='.'; 25 } 26 } 27 28 scanf("%d",&z); 29 for(i=1 ; i <= z ; i++) 30 scanf("%s",zxc[i]); 31 for(i=1 ; i <= z ; i++) 32 { 33 if(zxc[i][0]=='W')d[i]=1; 34 if(zxc[i][0]=='E')d[i]=2; 35 if(zxc[i][0]=='N')d[i]=3; 36 if(zxc[i][0]=='S')d[i]=4; 37 } 38 } 39 40 int dupe() 41 { int i,j,k,d=0; 42 for( k=1 ; k < tail ; k++) 43 if(f[k].x==f[tail].x && f[k].y==f[tail].y && f[k].d==f[tail].d)d=1; 44 if(d==1)return 1; 45 else return 0; 46 } 47 48 void bfs() 49 { int i,j,k,l,x0,y0; 50 f[1].d=1; 51 52 do{ 53 head++; 54 x0=f[head].x; 55 y0=f[head].y; 56 temp=f[head]; 57 x0 += di[d[temp.d]]; 58 y0 += dj[d[temp.d]]; 59 if(temp.d==z+1)return; 60 while(s[x0][y0]!='X'&& x0 >= 1 && y0 >= 1 && x0 <= n && y0 <= m ) 61 {if(v[x0][y0][f[head].d+1]==1) 62 { 63 x0 += di[d[temp.d]]; 64 y0 += dj[d[temp.d]]; 65 continue; 66 } 67 else v[x0][y0][f[head].d+1]=1; 68 tail++; 69 f[tail] = f[head]; 70 f[tail].d++; 71 f[tail].x=x0; 72 f[tail].y=y0; 73 f[tail].fa=head; 74 if(f[tail].d==z+1) 75 g[f[tail].x][f[tail].y]=1; 76 x0 += di[d[temp.d]]; 77 y0 += dj[d[temp.d]]; 78 } 79 80 }while(head<tail); 81 82 } 83 84 void output() 85 { 86 int i,j; 87 for(i=1 ; i <= n ; i++) 88 { 89 for(j=1 ; j <= m ; j++ ) 90 if(g[i][j]==1)printf("*"); 91 else printf("%c",s[i][j]); 92 if(i!=n)printf("\n"); 93 } 94 } 95 96 int main () 97 98 { 99 100 input(); 101 bfs(); 102 output(); 103 return 0; 104 }
Wikioi 3411 洪水
小浣熊松松和朋友到野外露营,没想到遇上了π年一次的大洪水,好在松松是一只爱观察的小浣熊,他发现露营地的地形和洪水有如下性质:
①露营地可以被看做是一个N*M的矩形方阵,其中左上角坐标为(1,1),右下角坐标为(n,m),每个格子(i,j)都有一个高度h(i,j)。
②洪水送(r,c)开始,如果一个格子被洪水淹没,那这个格子四周比它低(或相同)的格子也会被淹没。
现在松松想请你帮忙算算,有多少个格子不会被淹没,便于他和朋友逃脱。
【原有误数据已删除】
第一行包含两个整数n,m,表示矩形方阵右下角坐标。
以下n行,每行m个数,第i行第j个数表示格子(i,j)的高度。
最后一行包含两个整数r,c,表示最初被洪水淹没的格子。
输出仅一行,为永远不会被淹没的格子的数量。
3 3
1 2 3
2 3 4
3 4 5
2 2
5
对于90%的数据,保证随机生成。
对于100%的数据,1<=N,M<=1000。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<string> 5 6 using namespace std; 7 const int maxn = 2005; 8 int j[maxn][maxn],room[maxn][maxn]; 9 long long int total = 0,m,n; 10 struct pos{ 11 int x; 12 int y; 13 }; 14 pos q[4000000]; 15 pos dir[4]; 16 17 18 int bfs(int y,int x){ 19 int h = 0,t = 0; 20 q[0].y = y; 21 q[0].x = x; 22 int tx,ty; 23 while(h <= t){ 24 25 int r3 = 0; 26 for(r3 = 0;r3 < 4;r3++){ 27 x = q[h].x; 28 y = q[h].y; 29 tx = dir[r3].x; 30 ty = dir[r3].y; 31 if(y + ty >= 0 && y + ty < n && x + tx >= 0 && x + tx < m && room[y + ty][x + tx] && j[y + ty][x + tx]){ 32 t++; 33 q[t].y = y + ty; 34 q[t].x = x + tx; 35 j[y + ty][x + tx] = 0; 36 total--; 37 } 38 } 39 h++ ; 40 } 41 } 42 43 int main(){ 44 cin>>n>>m; 45 dir[0].x = -1;dir[0].y = 0; 46 dir[1].x = +1;dir[1].y = 0; 47 dir[2].x = 0;dir[2].y = -1; 48 dir[3].x = 0;dir[3].y = +1; 49 char cmd; 50 int r1 = 0,r2 = 0,temp = -1; 51 for(r1 = 0;r1 < n;r1++){ 52 for(r2 = 0;r2 < m;r2++){ 53 cin>>cmd; 54 if(cmd == '.') { 55 j[r1][r2] = 1; 56 room[r1][r2] = 1; 57 total++; 58 }else if(cmd == '#'){ 59 j[r1][r2] = 1; 60 room[r1][r2] = 0; 61 } 62 } 63 } 64 r1 = r2 =0; 65 for(r1 = 0;r1 < n;r1++){ 66 for(r2 = 0;r2 < m;r2++){ 67 if(room[r1][r2] && j[r1][r2]){ 68 j[r1][r2] = 0; 69 bfs(r1,r2); 70 } 71 72 } 73 } 74 cout<<total; 75 return 0; 76 }