zoukankan      html  css  js  c++  java
  • HDU 1010 Tempter of the Bone (DFS+可行性奇偶剪枝)

    <题目链接>

    题目大意:
    一个迷宫,给定一个起点和终点,以及一些障碍物,所有的点走过一次后就不能再走(该点会下陷)。现在问你,是否能从起点在时间恰好为t的时候走到终点。

    解题分析:
    本题恰好要在某一时刻到达,所以需要用到可行性剪枝中的奇偶剪枝,如果在某一点,它所剩的步数与到终点的最短距离之差是偶数,说明这种情况有可能恰好在规定时刻到达终点,否则不可能,将其剪去。

    #include <bits/stdc++.h>
    using namespace std;
    
    char mpa[8][8];
    int vis[8][8];
    int n,m,t,sx,sy,ex,ey;
    bool fp;
    const int dir[][2]={1,0,0,1,-1,0,0,-1};
    
    void dfs(int x,int y,int step){
        if(x==ex&&y==ey&&step==t){fp=true;return;}    //恰好达到终点
        int tmp=t-step-abs(ex-x)-abs(ey-y);    //重要的剪枝,可行性奇偶剪枝
        if(tmp<0 || tmp&1)return;
        if(step>t)return;    //超过规定时间,剪去
        if(fp)return;
        for(int k=0;k<4;k++){
            int nx=x+dir[k][0],ny=y+dir[k][1];
            if(nx<1||nx>n||ny<1||ny>m||vis[nx][ny]||mpa[nx][ny]=='X')continue;
            vis[nx][ny]=1;
            dfs(nx,ny,step+1);
            if(fp)return;    //已经找到答案,结束分支
            vis[nx][ny]=0;
        }   
    }
    int main(){
        while(~scanf("%d%d%d",&n,&m,&t),n||m||t){
            for(int i=1;i<=n;i++){
                scanf("%s",mpa[i]+1);
                for(int j=1;j<=m;j++){
                    if(mpa[i][j]=='S')sx=i,sy=j;
                    if(mpa[i][j]=='D')ex=i,ey=j;
                }
            }
            memset(vis,0,sizeof(vis));
            fp=false;
            vis[sx][sy]=1;dfs(sx,sy,0);
            fp?puts("YES"):puts("NO");
        }
    }
  • 相关阅读:
    JavaScript 多个空格替换成1个空格
    「DIARY」NOI2021 小结
    kubernetes常用命令总结
    Qt绘图(使用QPainter)翻转图像的两种方法
    android 11 R framework 新特证 开发备忘
    浏览器的缓存机制
    记el-tree 懒加载复选框回显的坑
    VUE根据文件流下载EXC
    西瓜视频播放器VUE
    推荐系统打散算法--权重
  • 原文地址:https://www.cnblogs.com/00isok/p/10530596.html
Copyright © 2011-2022 走看看