• HDU1072:Nightmare


    传送门

    题意

    给出一张n*m的图
    0.墙
    1.可走之路
    2.起始点
    3.终点
    4.时间重置点
    问是否能到达终点

    分析

    我的训练专题第一题,一开始我设个vis数组记录,然后写炸,不能处理重置点根vis的关系,然后看了iaccepted这篇blog,换了一种思路,加了一个很好的剪枝,0ms过,足可显示我的搜索思想差、实现差,切记!切记!

    trick

    1.dfs不能保证最先到达终点的为最短距离,不能打标记
    2.剪枝说明:如果当前到达该点时间少于该点剩余时间并且步数大于该点步数,则返回

    代码

    #include<cstdio>
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    inline int min(int x,int y){ return x<y?x:y; }
    int t,n,m,a[10][10],sx,sy,time[10][10],step[10][10];
    int b[4][2]={1,0,0,-1,-1,0,0,1},ans;
    bool check(int x,int y)
    {
        if(x<1||x>n||y<1||y>m||a[x][y]==0) return 0;return 1;
    }
    void dfs(int x,int y,int num,int st)
    {
        if(check(x,y)==0) return ;
        if(num<=0) return ;
        if(a[x][y]==3) { ans=min(ans,st);return ; }
        if(a[x][y]==4) num=6;
        if(num<=time[x][y]&&step[x][y]<=st) return ;
       // printf("x=%d y=%d
    ",x,y);
        time[x][y]=num;step[x][y]=st;
        R(i,0,4)
        {
            int xx=x+b[i][0],yy=y+b[i][1];
            dfs(xx,yy,num-1,st+1);
        }
    }
    int main()
    {
        for(scanf("%d",&t);t--;)
        {
            scanf("%d %d",&n,&m);
            F(i,1,n)F(j,1,m)
            {
                scanf("%d",&a[i][j]);
                if(a[i][j]==2) sx=i,sy=j;
                step[i][j]=100;time[i][j]=0;
            }
            ans=100;dfs(sx,sy,6,0);
            if(ans!=100) printf("%d
    ",ans);
            else puts("-1");
        }
    }
    
  • 相关阅读:
    HTTP协议【详解】——经典面试题
    原生JS的地区二级联动,很好理解的逻辑
    js操作字符串的常用方法
    移除input框type="number"在部分浏览器的默认上下按钮
    atom
    解决gitHub下载速度慢的问题
    ATOM常用插件推荐
    脚踝扭伤肿了怎么办
    这才是真正的电子科大
    月入 7000,怎么存钱?
  • 原文地址:https://www.cnblogs.com/chendl111/p/6648880.html
Copyright © 2020-2023  润新知