• zoj 2110 dfs,剪枝


    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1110

    题意:从起点走到目的地,不能回退到走过的格子,S表示起点,D表示终点,X表示墙,’ . ’表示空格,求在规定时间t内,能否到达终点。n,m表示迷宫的长和宽。

    思路:dfs,从起点开始搜,每个格子有四个方向,一个一个地搜。每搜一个格子,就要把格子设为X,因为不能走重复的格子,遇到墙壁或者边界就走不动,走不动就回退,要把格子恢复为‘ . ’,回到上一步的情况。如果某个位置满足条件,就停止搜索。如果全部分支都搜索完了还找不到解,就无解。

    其中有两处剪枝,一处是在主函数中,如果空格子数小于等于时间t,那么肯定无解。另一处是在dfs函数中,temp为当前剩余时间与到终点所要花的最短时间的差,如果为负或者是奇数就肯定不能成功。因为如果是奇数的话,就不满足那个,嗯,只能意会不能言传。。。

    #include<cstdio>
    #include<cmath>
    int n,m,t;
    int di,dj;
    int escape;
    char map[8][8];
    int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
    void dfs(int si,int sj,int cnt)
    {
        if(si>=n||sj>=m||si<0||sj<0) return;
        if(si==di && sj==dj &&cnt==t)
        {
            escape=1;
            return;
        }
        int temp=(t-cnt)-fabs(si-di)-fabs(sj-dj);
        if(temp<0 || temp%2!=0) return;//剪枝
        for(int i=0;i<4;i++)
            if(map[si+dir[i][0]][sj+dir[i][1]] != 'X')
            {
                map[si+dir[i][0]][sj+dir[i][1]]='X';
                dfs(si+dir[i][0],sj+dir[i][1],cnt+1);
                if(escape) return;
                else map[si+dir[i][0]][sj+dir[i][1]]='.';
            }
        return;
    }
    int main()
    {
        int si,sj;
        int wall;
        while(scanf("%d%d%d",&n,&m,&t) &&n&&m&&t)
        {
            getchar();
            wall=0;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    scanf("%c",&map[i][j]);
                    if(map[i][j]=='S')
                    {
                        si=i;
                        sj=j;
                    }
                    else if(map[i][j]=='D')
                    {
                        di=i;
                        dj=j;
                    }
                    else if(map[i][j]=='X')
                        wall++;
                }
                getchar();
            }
            if(n*m-wall<=t)//剪枝
               printf("NO\n");
            else
            {
               escape=0;
               map[si][sj]='X';
               dfs(si,sj,0);
               if(escape) printf("YES\n");
               else printf("NO\n");
            }
        }
    
        return 0;
    }
  • 相关阅读:
    [Codeforces 1290C]Prefix Enlightenment
    [JLOI 2015]战争调度
    [APIO 2010]特别行动队
    [CEOI 2004]锯木厂选址
    [USACO 08MAR]土地购买
    [HNOI 2017]大佬
    [NOI 2011]NOI 嘉年华
    [SHOI 2013]超级跳马
    [NOI 2005]瑰丽华尔兹
    [SCOI 2010]股票交易
  • 原文地址:https://www.cnblogs.com/54zyq/p/3072574.html
Copyright © 2020-2023  润新知