• zoj(2110)Tempter of the Bone(DFS+奇偶剪枝)


    剪枝很重要,可走的格数小于时间则减去,然后就是奇偶性剪枝
    可以把map看成这样:
    0 1 0 1 0 1
    1 0 1 0 1 0
    0 1 0 1 0 1
    1 0 1 0 1 0
    0 1 0 1 0 1
    从为 0 的格子走一步,必然走向为 1 的格子
    从为 1 的格子走一步,必然走向为 0 的格子
    即:
     0 ->1或1->0 必然是奇数步
     0->0 走1->1 必然是偶数步
    所以当遇到从 0 走向 0 但是要求时间是奇数的,或者, 从 1 走向 0 但是要求时间是偶数的 都可以直接判断不可达!

    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <fstream>
    #include <vector>
    #include <map>
    #include <queue>
    #include <stack>
    #include <math.h>
    #include <stdlib.h>
    using namespace std ;
    const int maxn = 55;
    char grid[maxn][maxn];
    int vis[maxn][maxn];
    int n,m,s,flag;
    int sx,sy,dx,dy;
    int dir[4][2] = {1,0,0,1,-1,0,0,-1};
    int cango(int x,int y){
        return x>=1&&x<=n&&y>=1&&y<=m;
    }
    void dfs(int x,int y,int step){
        if(flag)return ;//也是一种剪枝吧,不加上这句险些TLE
        if(step == s){
            if(x == dx && y == dy)
                flag = 1;
            return;
        }
        int temp = s - step - abs(dy - y)-abs(dx - x);
        if(temp<0||temp&1)//奇偶剪枝
            return;
        for(int i = 0;i < 4;i++){
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            if(cango(xx,yy)&&!vis[xx][yy]&&grid[xx][yy] != 'X'){
                vis[xx][yy] = 1;
                dfs(xx,yy,step+1);
                vis[xx][yy] = 0;
            }
        }
    }
    int main(){
        while(scanf("%d%d%d",&n,&m,&s)&&(n+m+s)){
            int wall = 0;
            for(int i = 1;i <= n;i++)
                scanf("%s",grid[i]+1);
            for(int i = 1;i <= n;i++)
                for(int j = 1;j <= m;j++){
                    if(grid[i][j] == 'S'){
                        sx = i;
                        sy = j;
                    }
                    if(grid[i][j] == 'D'){
                        dx = i;
                        dy = j;
                    }
                    if(grid[i][j] == 'X') wall++;
                }
            if(n*m - wall <= s){//可能性剪枝
                printf("NO\n");
                continue;
            }
            flag = 0;
            memset(vis,0,sizeof(vis));
            vis[sx][sy] = 1;
            dfs(sx,sy,0);
            if(flag)
                printf("YES\n");
            else
                printf("NO\n");
            //for(int i = 1;i <= n;i++)
              //  printf("%s\n",grid[i]+1);
        }
        return 0 ;
    }
  • 相关阅读:
    软件杯-题目和插件
    基于《河北省重大技术需求征集系统》的可用性和可修改性战术分析
    基于淘宝网的系统质量属性六大场景
    架构漫谈读后感
    06掌握需求过程阅读笔记之一
    大道至简读后感以及JAVA伪代码
    K8S学习笔记
    事务的七种传播类型、及案例
    香港身份证规则
    oracle函数
  • 原文地址:https://www.cnblogs.com/Roly/p/3056980.html
Copyright © 2020-2023  润新知