• 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
    ",a[x2][y2]);
    75       else                  printf("ORZ hzwer!!!
    ");
    76       fclose(stdin);fclose(stdout);
    77       return 0;
    78   }

     思路:见代码中解释

    Output

    6

  • 相关阅读:
    [android] 帧布局
    [android] 表格布局和绝对布局
    使用LVS实现负载均衡原理及安装配置详解
    学习Docker之Dockerfile的命令
    使用docker-compose部署nginx
    CentOS Bash 命令补全增强软件包 bash-completion
    “三次握手,四次挥手”你真的懂吗?
    0777 0的意思
    linux文件或目录权限修改后如何恢复(备份了权限就能恢复)
    centos7进入单用户模式
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6073015.html
Copyright © 2020-2023  润新知