码迷,mamicode.com
首页 > Web开发 > 详细

POJ3009 Curling 2.0【DFS】

时间:2015-04-14 18:03:44      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

http://poj.org/problem?id=3009


题目大意:

一种在宽为M高为N大小的矩阵上玩的冰壶游戏,起点字符为‘2‘,终点字符为‘3‘,矩阵上‘0‘为可移动区域,

‘1‘为石头区域。冰壶刚开始是静止的,每走一步都会选择某个方向运动,而且会沿着该方向一直运动不停,

也不会改变方向,除非冰壶碰到石头或者到达终点,才会停下(这算一步)。冰壶在运动的时候,不能改变方

向。冰壶碰到石头会变成静止状态,这时候石头会破裂,该区域变为可移动区域,而冰壶就可以改变方向了。

冰壶一旦走到终点就不再移动。问:冰壶从起点到终点最少停多少次(走多少步)?


思路:

1)记录起点和终点位置,并将起点和终点标为可移动区域。

2)因为需要找到所有通路中的最短步数,所以用DFS寻找从起点到终点的最短步数。

3)每走一步到静止之后,可选择四个方向,DFS继续下一步。

4)在撞到石头破裂后需要继续下一步,这时候需要回溯回来重新选择方向。

5)冰壶不可以出界。

6)不能超过10步。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int vis[25][25];
int N,M;
int flag,SumStep;
int Sx,Sy,Ex,Ey;
int Dire[4][2] = {0,1,0,-1,1,0,-1,0};

void DFS(int x,int y,int step)
{
    int tx,ty;
    if(step >= 10)      //超过10步算失败
        return ;
    for(int i = 0; i < 4; i++)
    {
        if(!vis[x+Dire[i][0]][y+Dire[i][1]])        //选择可移动的方向
        {
            tx = x;
            ty = y;
            while(!vis[tx+Dire[i][0]][ty+Dire[i][1]])   //移动到障碍点或是边界点前
            {
                tx = tx + Dire[i][0];
                ty = ty + Dire[i][1];
                if(tx == Ex && ty == Ey)
                {
                    if(SumStep > step+1)        //找到路径
                        SumStep = step+1;
                    flag = 1;
                    return ;
                }
                if(tx < 0 || tx >= N || ty < 0 || ty >= M)  //判断越界
                    break;
            }
            if(tx >= 0 && tx < N && ty >= 0 && ty < M && step+1 < 10)   //撞上障碍后
            {
                vis[tx+Dire[i][0]][ty+Dire[i][1]] = 0;      //石头破裂,变为可移动区域
                DFS(tx,ty,step+1);                          //选择方向,继续移动
                vis[tx+Dire[i][0]][ty+Dire[i][1]] = 1;      //回溯回来,继续选择上一步方向
            }
        }
    }
}

int main()
{
    while(~scanf("%d%d",&M,&N) && (M||N))
    {
        memset(vis,0,sizeof(vis));  
        for(int i = 0; i < N; i++)
        {
            for(int j = 0; j < M; j++)
            {
                scanf("%d",&vis[i][j]);
                if(vis[i][j] == 2)  //记录起点位置
                {
                    Sx = i;
                    Sy = j;
                    vis[i][j] = 0;
                }
                if(vis[i][j] == 3)  //记录终点位置
                {
                    Ex = i;
                    Ey = j;
                    vis[i][j] = 0;
                }
            }
        }
        flag = 0;
        SumStep = 0xffffff0;
        DFS(Sx,Sy,0);
        if(!flag)
            SumStep = -1;

        printf("%d\n",SumStep);
    }

    return 0;
}


POJ3009 Curling 2.0【DFS】

标签:

原文地址:http://blog.csdn.net/lianai911/article/details/45044693

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!