zoukankan      html  css  js  c++  java
  • 信息战(九)——水淹七军——南阳1321

    题目:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=1321

    过程:WA了好多次,错误原因:

    1.初始化数组record[]操作:memset(record,0,sizeof(record)),放错了位置,每一个放水点,就是重新搜索一次,初始化应该dsf放在之前。一开始只我放在了一组数据开始之前
    2.在一个放水点里,递归调用,走过的位置标记,但是不需要及时还原,会导致runtime error,超时。

    思路:跟迷宫问题大同小异了从放水点深度搜索,每一个位置有四个方向可以走(四种选择),要注意的是可以行走的条件,只要放水点的位置比当前准备走的位置高,就可以淹没当前点,继续遍历搜索,遍历结束 发现还没有淹没司令部,重新搜索下一个放水点,注意在这之前要初始化标记数组(标记是否走过,避免重复行走)。若搜索到了,下面的放水点就不用搜索了。(大神说,水淹没的地方,都变成放水点的高度,搜索的过程中及时更新a[][]地图中点的高度,这一步确实节省了时间,但是不需要。因为后一个放水点如果比前一个高,那更新就做了无用功了,不论如何都要经过他;若放水点比前一个放水点低,如果不更新,会走的时间长一点。嗯....好吧,其实还是大神想的周到,更新总是好的)。

    dfs()函数依然分为两部分,if部分(结束 标志),else部分(每一次,每一层的选择),dfs的参数,写变化的部分(到了第几层,第几个位置)。

    代码:

     1 #include<stdio.h>
     2 #include<memory.h>
     3 int a[205][205],flag,m,n,m1,n1,I,J,D[4][2]={-1,0,1,0,0,-1,0,1},record[205][205];//D四个方向,(m1,n1)司令部的位置,record[]记录是否走过
     4 void dfs(int x,int y){
     5     int nx,ny;
     6     record[x][y]=1;//表遍历过(避免重复走)
     7     //if部分(如果淹到了司令部)
     8     if(x==m1&&y==n1){//水淹到了司令部
     9         flag=1;//淹没了
    10         return;
    11     }
    12     //else部分(选择,四个方向)
    13     else{
    14     for(int i=0;i<4;i++)//四个方向
    15     {
    16             nx=x+D[i][0];//四个方向遍历
    17             ny=y+D[i][1];
    18             if(record[nx][ny]==0&&a[I][J]>=a[nx][ny]&&nx>0&&nx<=m&&ny>0&&ny<=n) //若下一个方向上的点 没有走过,放水点比当前点的高度高或相等 ,水流可经过,继续遍历
    19             {
    20                 dfs(nx,ny);
    21                 //record[x][y]=0;//不必还原,还原只会走重复的路,一直循环,导致超时
    22             }
    23     }
    24     }
    25 }
    26 int main(){
    27     int K,N,i,j;
    28    freopen("1.txt","r",stdin);
    29     scanf("%d",&K);//K组数据
    30     //地图(各点的高度)
    31     while(K--){
    32     flag=0;//初始化
    33     scanf("%d %d",&m,&n);
    34     memset(record,0,sizeof(record));
    35     for(i=1; i<=m; i++)//从1开始存,与位置信息相对应
    36     {
    37         for(j=1; j<=n; j++)
    38         {
    39             scanf("%d",&a[i][j]);
    40         }
    41     }
    42     scanf("%d %d",&m1,&n1);//指挥部位置
    43     scanf("%d",&N);
    44     for(i=0;i<N;i++){
    45         scanf("%d %d",&I,&J);//放水的位置
    46     if(!flag){//没被淹没,看下一个放水点
    47     memset(record,0,sizeof(record));
    48     dfs(I,J);//调用dfs,判断是否可以到 指挥部
    49     }
    50     }
    51     if(flag)
    52          printf("Yes
    ");
    53     else
    54         printf("No
    ");
    55     }
    56 return 0;
    57 }
  • 相关阅读:
    解决ssh: connect to host github.com port 22: Connection refused
    sudo/su命令免密执行
    Linux tar.gz、tar、bz2、zip 等解压缩、压缩命令详解
    项目实战——校验文件名和邮箱地址
    项目实战:判断闰年平年并输出某月的天数
    ubuntu软件更新时出现没有Release文件
    项目实战:根据出生日期判断星座
    项目实战--实现淡旺季飞机票打折
    xxx.java:1: 错误: 类xxx是公共的, 应在名为 xxx.java 的文件中声明 public class xxx
    32位int整数范围
  • 原文地址:https://www.cnblogs.com/li-yaoyao/p/9498377.html
Copyright © 2011-2022 走看看