hdu 1010 Tempter of the Bone(dfs+枝剪)

本文介绍了一道典型的迷宫问题——HDU 1010,通过深度优先搜索(DFS)解决在一个n*m的地图中如何在特定步数内从起点到终点的问题,并使用了奇偶枝剪枝优化算法来提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1010

题意:n*m的地图,规定恰好在第t步到达终点'D',起点是‘S’,墙是‘X’

思路:还是走迷宫的题,每次上下左右走,暴力所有情况,找到恰好是t步的路径,每次回溯再回到初始状态。

    但还有一个奇偶枝剪,意思就是要求的最短路径是|ex-sx|+|ey-sy|,若要到达终点,必须多走偶数步。

    什么奇偶枝剪,在main里判断一下即可。

#include<bits/stdc++.h>
using namespace std;
int n,m,t,sx,sy,ex,ey,xnum;
bool visit[10][10],flg;
char mp[10][10];
const int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};

void dfs(int x, int y, int step) {
    if(flg) return;  //一种情况即可
    if(step == t && x == ex && y == ey) {
        flg=true;
        return;
    }
    if(step >= t) return;  //搜索的路径大于t时返回
    //int dis = abs((double)x-ex) + abs((double)y-ey);
    //dis = t-dis-step;
    //if(dis<0 || dis%2) return;//奇偶剪枝
    for( int i=0; i<4; ++i) {
        int tx = x+dir[i][0];
        int ty = y+dir[i][1];
        int tstep = step+1;
        if(tx>=0 &&tx<n &&ty>=0 &&ty<m &&!visit[tx][ty] &&mp[tx][ty] != 'X') {
            visit[tx][ty] = true;
            dfs(tx,ty,tstep);
            visit[tx][ty] = false;//回溯
        }
    }
    return;
}

int main(){
    while(scanf("%d%d%d",&n,&m,&t)&&(n+m+t)){
        xnum=0;
        flg=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++){
                cin>>mp[i][j];
                visit[i][j]=false;
                if(mp[i][j]=='S'){
                    visit[i][j]=true;
                    sx=i;
                    sy=j;
                }
                if(mp[i][j]=='D'){
                    ex=i;ey=j;
                }
                if(mp[i][j]=='X')
                    ++xnum;
            }
        int dis = abs((double)sx-ex) + abs((double)sy-ey);
        if(t%2==0&&dis%2==1|| t%2==1&&dis%2==0){
            cout<<"NO"<<endl;
            continue;
        }
        if(n*m-xnum>t)  //这点也很着重要,如果可走的步数比赛t还小直接pass
            dfs(sx,sy,0);
        if(flg)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值