广搜——路径寻找

Tyvj 1117 拯救ice-cream

背景

天好热……Tina顶着那炎炎的烈日,向Ice-cream home走去……
可是……停电了……
冰淇淋们躺在Ice-cream home的冰柜里,慢慢地……慢慢地……融化…………
你说,她能赶在冰淇淋融化完之前赶到Ice-cream home去吗?

描述

给你一张坐标图,s为Tina的初始位置,m为Ice-cream home的位置,‘.’为路面,Tina在上面,每单位时间可以移动一格;‘#’为草地,Tina在上面,每两单位时间可以移动一格(建议不要模仿—毕竟Tina还小);‘o’是障碍物,Tina不能在它上面行动。也就是说,Tina只能在路面或草地上行走,必须绕过障碍物,并到达冰淇淋店。但是…………不保证到达时,冰淇淋还未融化,所以……就请聪明的你……选择最佳的方案啦…………如果,Tina到的时候,冰淇淋已经融化完了,那她可是会哭的。

输入格式

依次输入冰淇淋的融化时间t(0<t<1000),坐标图的长x,宽y(5<=x,y<=25){太长打起来好累……},和整张坐标图。

输出格式

判断按照最优方案是否可以赶在冰淇淋融化之前到达冰淇淋店(注:当T=最优方案所用时间,则判断为未赶到),如赶到,输出所用时间;如未赶到,输出Tina的哭声——“55555”(不包括引号)。

测试样例1

输入

11 
10 

......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 } 
View Code

 Wikioi 1026 逃跑的拉尔夫

题目描述 Description

年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置。

那个装置太旧了,以至于只能发射关于那辆车的移动路线的方向信息。

编写程序,通过使用一张小镇的地图帮助警察局找到那辆车。程序必须能表示出该车最终所有可能的位置。

小镇的地图是矩形的,上面的符号用来标明哪儿可以行车哪儿不行。“.”表示小镇上那块地方是可以行车的,而符号“X”表示此处不能行车。拉尔夫所开小车的初始位置用字符的“*”表示,且汽车能从初始位置通过。

汽车能向四个方向移动:向北(向上),向南(向下),向西(向左),向东(向右)。

拉尔夫所开小车的行动路线是通过一组给定的方向来描述的。在每个给定的方向,拉尔夫驾驶小车通过小镇上一个或更多的可行车地点。

输入描述 Input Description

输入文件的第一行包含两个用空格隔开的自然数R和C,1≤R≤50,1≤C≤50,分别表示小镇地图中的行数和列数。

以下的R行中每行都包含一组C个符号(“.”或“X”或“*”)用来描述地图上相应的部位。

接下来的第R+2行包含一个自然数N,1≤N≤1000,表示一组方向的长度。

接下来的N行幅行包含下述单词中的任一个:NORTH(北)、SOUTH(南)、WEST(西)和EAST(东),表示汽车移动的方向,任何两个连续的方向都不相同。

输出描述 Output Description

输出文件应包含用R行表示的小镇的地图(象输入文件中一样),字符“*”应该仅用来表示汽车最终可能出现的位置。

 

样例输入 Sample Input

4 5

.....

.X...

...*X

X.X..

3

NORTH

WEST

SOUTH

 

样例输出 Sample Output

.....

*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 }
View Code

Wikioi 3411 洪水

题目描述 Description

小浣熊松松和朋友到野外露营,没想到遇上了&pi;年一次的大洪水,好在松松是一只爱观察的小浣熊,他发现露营地的地形和洪水有如下性质:

①露营地可以被看做是一个N*M的矩形方阵,其中左上角坐标为(1,1),右下角坐标为(n,m),每个格子(i,j)都有一个高度h(i,j)。

②洪水送(r,c)开始,如果一个格子被洪水淹没,那这个格子四周比它低(或相同)的格子也会被淹没。

现在松松想请你帮忙算算,有多少个格子不会被淹没,便于他和朋友逃脱。

【原有误数据已删除】

输入描述 Input Description

第一行包含两个整数n,m,表示矩形方阵右下角坐标。

以下n行,每行m个数,第i行第j个数表示格子(i,j)的高度。

最后一行包含两个整数r,c,表示最初被洪水淹没的格子。

输出描述 Output Description

输出仅一行,为永远不会被淹没的格子的数量。

样例输入 Sample Input

3 3

1 2 3

2 3 4

3 4 5

2 2

样例输出 Sample Output

5

数据范围及提示 Data Size & Hint

对于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 }
View Code
posted @ 2015-09-27 07:29  ACforever  阅读(472)  评论(0编辑  收藏  举报