Curling 2.0 POJ - 3009(DFS,障碍关联位置)

 题意:大模拟DFS就是模拟摸摸摸

分析:结合代码给出,见下方代码

收获:对于萌新来说每一次都有新收获。

写DFS还是要从整体的角度看问题,比如这个题中的障碍的撞碎问题怎么模拟,可以利用每次深搜到尽头之后修复被撞碎的障碍来保证其他的DFS正确(看的学长的思路,这一手很皮的)。

对于一直前进的处理就是for()来确定方向,不停向前for(int j=0; ;j++)利用j来求出x和y的实时坐标。


#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int m,n;
int s[50][50];
int bx,by,ex,ey;
int steep;
int dx[]= {1,0,-1,0};//前进的方向
int dy[]= {0,1,0,-1};//前进的方向
int min_steep=1500000;
bool not_in(int x1,int y1)//判断是否越界
{
    if(x1<0||x1>=m||y1<0||y1>=n) return true;
    return false;
}
void DFS(int x,int y,int cur)
{
    if(cur>10) return ;//超过十步就结束搜索。
    if(cur>=min_steep) return ;//如果继续搜索下去一定找不到比现在更短的路径的时候就结束搜索
 
    if(s[x][y]==3)//到达终点 
    {
 
        min_steep=min(cur,min_steep);
        return ;
    }
    for(int i=0; i<4; i++)
    {
        for(int j=1;; j++)//一直往前
        {
            int nx=x+j*dx[i];
            int ny=y+j*dy[i];//当前点的坐标
            if(not_in(nx,ny))
            {
                break;
            }
 
            if(j==1&&s[nx][ny]==1) break;//被卡住了就结束

            if(s[nx][ny]==3)
            {
                DFS(nx,ny,cur+1);
                return;
            }
            if(s[nx][ny]==1)
            {
                int lx=nx-dx[i];
                int ly=ny-dy[i];
                s[nx][ny]=0;
                DFS(lx,ly,cur+1);
                s[nx][ny]=1;//这里很巧妙,在每次深度搜索到尽头之后会再修复破坏的障碍,让下次的深搜再使用,双击666
                break;
            }

        }
    }
}
int main ()
{
    while(cin >> n >> m)
    {
        min_steep=150000;
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<n; j++)
            {
                scanf("%d",&s[i][j]);
                if(s[i][j]==2)
                {
                    bx=i;
                    by=j;
                }
                if(s[i][j]==3)
                {
                    ex=i;
                    ey=j;
                }
            }

        }
//        cout << bx << " " << by << endl;
//        cout << ex << " " << ey << endl;

        DFS(bx,by,0);
        if( min_steep ==150000)

            cout << "-1" << endl;
        else
            cout << min_steep <<endl;

    }
    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值