POJ 3009 Curling 2.0

题意:给定一个n*m的矩阵。里面有一些点。0代表可移动空间,1代表blocks,2代表起点,3代表结束点。

在点2开始,朝四个方向中的一个移动,只有碰到1或者3或者出界才会停止。

如果碰到1,则停在到达1之前的位置,然后1消失,变成0。

如果碰到3,则输出到达3的最少步骤,如果超过10则输出-1。

如果失败,则继续下个方向,若所有方向都无法到达。输出-1。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 25
#define inf 1<<28
using namespace std;

int n,m;
int Map[Max][Max];
int sx,sy;
int movex[4]= {0,0,1,-1};//右,左,下,上
int movey[4]= {1,-1,0,0};
int inmap(int x,int y)
{
    if(x>0&&y>0&&x<=n&&y<=m)
        return 1;
    return 0;
}
void show()
{
    int i,j;
    getchar();
    cout<<endl;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
            cout<<Map[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
}
int dfs(int x,int y,int step)
{
    //show();
    int i,j;
    if(step>10)//如果步数超过10,返回失败
        return -1;
    int maxstep=11;
    for(i=0; i<4; i++)
    {
        int tempx=x,tempy=y;//下一步
        tempx+=movex[i];
        tempy+=movey[i];
        if(inmap(tempx,tempy)&&Map[tempx][tempy]!=1)//判断下一步是否可以走
        {
            while(Map[tempx][tempy]!=1&&inmap(tempx,tempy))//向着这个方向一直走下去,直到碰到1或者3或者出界。
            {
                if(Map[tempx][tempy]==3)//如果碰到3,则返回成功的步数
                    return step;
                tempx+=movex[i];
                tempy+=movey[i];
            }
            if(inmap(tempx,tempy))//判断是否出界,若没有出界,则将这个blocks打掉,即换为0。
            {
                Map[tempx][tempy]=0;//将blocks打掉
                int temp=dfs(tempx-movex[i],tempy-movey[i],step+1);//返回到达blocks之前的最后位置继续往下找
                if(temp!=-1)
                {
                    if(temp<maxstep)//更新maxstep
                    maxstep=temp;
                }
                Map[tempx][tempy]=1;
            }
        }
    }
    if(maxstep==11)//如果maxstep没被更新,则说明失败
    return -1;
    return maxstep;
}
int main()
{
    int i,j,k,l;
    while(scanf("%d%d",&m,&n)&&(n+m))
    {
        for(i=1; i<=n; i++)
            for(j=1; j<=m; j++)
            {
                scanf("%d",&Map[i][j]);
                if(Map[i][j]==2)
                {
                    sx=i;
                    sy=j;
                }
            }
        int ans=dfs(sx,sy,0)+1;
        if(ans>10||!ans)
        cout<<-1<<endl;
        else
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值