首页 > 代码库 > HDU 1010 Tempter of Bone DFS + 奇偶剪枝

HDU 1010 Tempter of Bone DFS + 奇偶剪枝

奇偶剪枝:

对于从起始点 s 到达 终点 e,走且只走 t 步的可达性问题的一种剪枝策略。

如下列矩阵 :

任意 0 到达 任意 0,所需步数均为偶数,到达任意 1 ,均为奇数。反之亦然

所以有,若s走且只走 t 步可到达e,则必有t >= abs(s.x - e.x) + abs(s.y - e.y),且 (t&1) == ((abs(s.x - e.x) + abs(s.y - e.y))&1)。

否则必不可达。

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <stack>
#include <map>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long LL
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 1000000007
#define LM(a,b) (((ULL)(a))<<(b))
#define RM(a,b) (((ULL)(a))>>(b))

using namespace std;

char Map[10][10];

bool mark[10][10];

struct Q
{
    int x,y,t;
};

int jx[] = {-1, 0, 1, 0};
int jy[] = { 0,-1, 0, 1};

bool dfs(int sx,int sy,int ans,int ex,int ey,int n,int m,int t)
{
    if(ans == t)
    {
        if(sx == ex && sy == ey)
            return true;
        else
            return false;
    }
    else if(sx == ex && sy == ey)
        return false;

    if(((abs(ex-sx) + abs(ey-sy))&1) != ((t-ans)&1))
        return false;

    for(int i = 0;i < 4 ; ++i)
    {
        int tx = sx+jx[i];
        int ty = sy+jy[i];

        if(1 <= tx && tx <= n && 1 <= ty && ty <= m && Map[tx][ty] != ‘X‘ && mark[tx][ty] == false)
        {
            mark[tx][ty] = true;
            if(dfs(tx,ty,ans+1,ex,ey,n,m,t) == true)
                return true;
            mark[tx][ty] = false;
        }
    }
    return false;
}

void Solve(int n,int m,int t)
{
    int i,j;

    int sx,sy,ex,ey;

    for(i = 1;i<= n; ++i)
    {
        for(j = 1;j <= m; ++j)
        {
            if(Map[i][j] == ‘S‘)
            {
                sx = i,sy = j;
            }
            else if(Map[i][j] == ‘D‘)
            {
                ex = i,ey = j;
            }
        }
    }

    memset(mark,false,sizeof(mark));

    mark[sx][sy] = true;

    if(dfs(sx,sy,0,ex,ey,n,m,t) == true)
        printf("YES\n");
    else
        printf("NO\n");
}

int main()
{
    int n,m,t;

    int i;

    while(scanf("%d %d %d",&n,&m,&t) && (n||m||t))
    {
        for(i = 1;i <= n ; ++i)
        {
            scanf("%s",Map[i]+1);
        }

        Solve(n,m,t);

    }
    return 0;
}