POJ3009 Curling 2.0 DFS

本文深入探讨了深度优先搜索(DFS)算法的优化技巧,并通过一个具体的编程问题实例,讲解了如何利用DFS解决迷宫寻路问题。文章强调了使用while循环替代递归在特定场景下的优势,以及在算法中加入剪枝策略的重要性,避免了不必要的计算,显著提高了算法效率。

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

果然退步到不行了。。这道dfs并不难,思路也大差不多,就是一直写不对。。。心情复杂.jpg

然后看了别人的写法,要注意几点:1. 一直前进到底时用while不用dfs会更方便(这个可以和之前做的ZOJ1259模拟栈的出栈操作放在一起想,如果某项操作中不会出现别的情况就直接写while而不要递归,否则就一点点来);   2.用sign标记某条路行不行得通,能走再进行后续(一直前进);   3.一个block消除之后要退回上一步前进,同时num++;   4.num>10和ans<num要优化剪枝!!否则会TLE!!   5.注意回溯,dfs之后变回来。   附上AC代码:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> pp;
#define mkp make_pair

int n,m;//行,列
int a[25][25];
pp st,en;
int ans;
int dx[6]={0,1,0,-1,0};//1234
int dy[6]={0,0,-1,0,1};
bool judge(int x,int y)//判断能否前进
{
    if(x<0||y<0||x>=n||y>=m||a[x][y]==1) return false;
    else return true;
}
void dfs(int x,int y,int num)
{
    if(num>10||ans<num)//优化剪枝!否则会TLE!
        return;
    if(judge(x,y)==false) return;
    for(int i=1;i<=4;i++)//4个方向
    {
        int xx=x+dx[i],yy=y+dy[i];
        bool sign=false;//标记这条路能不能走
        while(judge(xx,yy))//一直前进到底
        {
            sign=true;//这个方向能走
            if(a[xx][yy]==3)
            {
                ans=min(ans,num);
                return;
            }
            xx+=dx[i],yy+=dy[i];
        }
        if(xx<0||yy<0||xx>=n||yy>=m||sign==false)//false,不可少!
            continue;
        //block
        a[xx][yy]=0;
        dfs(xx-dx[i],yy-dy[i],num+1);//退回上一步
        a[xx][yy]=1;//注意回溯
    }
}

int main()
{
    while(scanf("%d%d",&m,&n)==2)
    {
        if(n==0&&m==0) break;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i][j]);
                if(a[i][j]==2)
                    st.first=i,st.second=j;
                if(a[i][j]==3)
                    en.first=i,en.second=j;
            }
        ans=INF;
        dfs(st.first,st.second,1);
        if(ans==INF||ans>10) printf("-1\n");
        else printf("%d\n",ans);
    }
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值