16.1117 NOIP 模拟赛
水灾(sliker.cpp/c/pas) 1000MS 64MB
大雨应经下了几天雨,却还是没有停的样子。土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没。
CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D S”。其中“X”表示石头,水和人都不能从上面经过。“.”表示平原,CCY和洪水都可以经过。“*”表示洪水开始地方(可能有多个地方开始发生洪水)。“D”表示CCY的别墅。“S”表示CCY现在的位置。
CCY每分钟可以向相邻位置移动,而洪水将会在CCY移动之后把相邻的没有的土地淹没(从已淹没的土地)。
求CCY回到别墅的最少时间。如果聪哥回不了家,就很可能会被淹死,那么他就要膜拜黄金大神涨RP来呼叫直升飞机,所以输出“ORZ hzwer!!!”。
输入文件 sliker.in
输出文件 sliker.out
Input
3 3
D.*
…
.S.
Output
3
Input
3 3
D.*
…
..S
Output
ORZ hzwer!!!
Input
3 6
D…*.
.X.X..
….S.
1 #include<cstdio>
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 using namespace std;
6 int hx[60],hy[60],h;
7 int x1,y1,x2,y2;
8 int n,m;
9 char c[60];
10 bool b[60][60],tx[51][51];
11 int tim[60][60],a[60][60];
12 int dx[]={1,0,-1,0};
13 int dy[]={0,1,0,-1};
14 int xx[2510],yy[2510];
15 void sousuo(int t,int x,int y)
16 {
17 tim[x][y]=min(t,tim[x][y]);
18 for(int i=0;i<4;i++)
19 {
20 int xx=x+dx[i],yy=y+dy[i];
21 if(b[xx][yy]&&xx>0&&xx<=n&&yy>0&&yy<=m&&t+1<tim[xx][yy])
22 sousuo(t+1,xx,yy);
23 }
24 }
25 int main()
26 {
27 freopen("sliker.in","r",stdin);
28 freopen("sliker.out","w",stdout);
29 scanf("%d%d",&n,&m);
30 for(int i=1;i<=n;i++)
31 {
32 cin>>c;
33 for(int j=0;j<m;j++)
34 {
35 switch(c[j])// b数组标记能否走这个格子
36 {
37 case '.':b[i][j+1]=true;break;
38 case 'S':x1=i;y1=j+1;b[i][j+1]=true;break;
39 case 'D':x2=i;y2=j+1;b[i][j+1]=false;break;// 别墅暂时标记为不能走
40 case '*':++h;hx[h]=i;hy[h]=j+1;break;// 记录洪水发生地点
41 case 'X':b[i][j+1]=false;break;
42 }
43 }
44 }
45 memset(tim,127,sizeof(tim));// tim表示洪水到达该格点的最少时间
46 memset(a,127,sizeof(a));// a表示人走到该格点的最少时间
47 for(int i=1;i<=h;i++)
48 sousuo(0,hx[i],hy[i]);// 洪水所有的初始地点
49 b[x2][y2]=true;// 将别墅 标记为能走
50 xx[1]=x1,yy[1]=y1;
51 int head=0,tail=1;
52 a[x1][y1]=0;
53 tx[x1][y1]=true;// tx 数组标记是否已经走过 true为已经走过
54 while(head<=tail)
55 {
56 ++head;
57 int x=xx[head],y=yy[head];
58 for(int i=0;i<4;i++)
59 {
60 int mx=x+dx[i],my=y+dy[i];
61 if(b[mx][my]==true&&mx>0&&mx<=n&&my>0&&my<=m&&a[x][y]+1<tim[mx][my])
62 {// a[x][y]+1<tim[mx][my] 人能够在洪水到达该格子之前到达就说明可以走,否则--
63 a[mx][my]=min(a[mx][my],a[x][y]+1);
64 if(tx[mx][my]==false)
65 {
66 tx[mx][my]=true;
67 tail++;
68 xx[tail]=mx;
69 yy[tail]=my;
70 }
71 }
72 }
73 }
74 if(a[x2][y2]<a[0][0]) printf("%d\n",a[x2][y2]);
75 else printf("ORZ hzwer!!!\n");
76 fclose(stdin);fclose(stdout);
77 return 0;
78 }
思路:见代码中解释
Output
6