POJ3009 Curling 2.0(DFS)

题意:地图上有个冰壶,0代表冰面,1代表有石头,2代表冰壶初始位置,3代表目标位置。求冰壶运动到终点的最短步数,冰壶运动有几个规则:

1、冰壶沿一个方向运动就会停不下来,除非碰到石头或者到达终点。

2、如果碰到石头,冰壶就会停在石头旁边的区域,而石头会消失,也就是从“1”变成“0”。

3、如果冰壶静止的时候挨着石头,那么冰壶就不能向这个方向运动。

4、如果没有石头或终点,冰壶会一直运动到界外,游戏失败。

5、如果步数超过十步,游戏也会失败。


规则1、2、3见图一,一个示例见图二。


思路:总结游戏规则,归纳出几种冰壶运动的情况:

1、静止时:旁边是石头时不能移动,是终点或者冰面则可以移动。

2、运动时:运动尽头是石头或终点则可以停下来,即可行,算作运动一步,尽头是冰面时则不能移动。

结合以上,对与冰壶当前位置,先判断四个方向能否移动,能移动的话再用函数jud根据当前方向终点判断是否能移动,以此进行DFS。


//#include<bits/stdc++.h>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF  0x3f3f3f3f
typedef long long  LL;
int m,n,ans,sx,sy,gx,gy;
int maze[25][25];
bool vis[25][25];
int d[2][4]={-1,0,0,1,0,-1,1,0};
bool jud(int &x,int &y,int f){//根据当前方向的终点判断能否移动
    x+=d[0][f];
    y+=d[1][f];
    while(x>=0&&x<n&&y>=0&&y<m){
        if(maze[x][y]==1||maze[x][y]==3){
            return true;
        }
        x+=d[0][f];
        y+=d[1][f];
    }
    return false;
}
void dfs(int x,int y,int k){//当前坐标、步数
    if(k>=ans)return;
    if(x==gx&&y==gy){
        ans=min(ans,k);
        return;
    }
    int dx,dy;
    for(int i=0;i<4;++i){
        dx=x+d[0][i],dy=y+d[1][i];
        if(dx>=0&&dx<n&&dy>=0&&dy<m&&maze[dx][dy]!=1){
            if(3==maze[dx][dy]){//相邻格子是终点,步数加一,退出本次DFS
                ans=1+k;
                return;
            }
            if(jud(dx,dy,i)){//判断能否移动
                if(maze[dx][dy]==1){
                    maze[dx][dy]=0;
                    dfs(dx-d[0][i],dy-d[1][i],1+k);
                    maze[dx][dy]=1;
                }
                else if(3==maze[dx][dy]){
                    ans=1+k;
                }
            }
        }
    }
}
int main(){
    while(scanf("%d%d",&m,&n),m+n){
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                scanf("%d",&maze[i][j]);
                if(maze[i][j]==2){
                    sx=i,sy=j;
                }
                if(maze[i][j]==3){
                    gx=i,gy=j;
                }
            }
        }
        ans=11;
        dfs(sx,sy,0);
        if(ans>10)ans=-1;
        printf("%d\n",ans);
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值