大意:奥林匹克冰球运动的一种变体,给定你一个特定的迷宫,出口以及入口,从出口到入口最小走几步。

思路:

(1)不可用BFS,冰球每次撞击障碍物时,障碍物会消失。而BFS会导致整个迷宫状态的改变,所以只能用DFS。

(2)当冰球是运动时,撞击障碍物,然后停下,需要回溯。静止时,不可能向有障碍物的方向走。

(3)冰球不向普通的走法一样是一步一步走,而是一条直线的走。它可能在运动的过程中会超出边界,这就需要判断,只有继续递归调用时,步数才会加1。

 

CODE:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

const int SIZE = 21;
const int INF = 0x3f3f3f3f;
int maze[SIZE][SIZE];
int min_step, step;
int bx, by;
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,-1,1};
int n, m;


void init()
{
    memset(maze, INF, sizeof(maze));
    step = 0;
    min_step = 0x3f3f3f3f;
    bx = by = 0;
}


int check(int x, int y)
{
    if(x >= 0 && y >= 0 && x < n && y < m )
        return 1;
    return 0;
}



void dfs(int x, int y, int step)
{
    if(step > 10return ;               //剪枝 
    for(int i = 0; i < 4; i++)
    {
        int xx = x+dx[i];
        int yy = y+dy[i];
        if(!check(xx, yy)) continue;           //超出边界 
        if(maze[xx][yy] == 1continue;        //静止状态而旁边是障碍物 
        while(maze[xx][yy] == 0)
        {
            xx += dx[i];
            yy += dy[i];
            if(!check(xx, yy)) break;          //超出边界 
        }
        if(check(xx, yy))
        {
            if(maze[xx][yy] == 3)            //走到目标 
            {
                if(step+1 < min_step)
                {
                    min_step = step+1;        //状态的更新 
                }    
            }
            if(maze[xx][yy] == 1)             //运动时遇到障碍物并停下。 
            {
                maze[xx][yy] = 0;
                dfs(xx-dx[i], yy-dy[i], step+1);     //不可用++step
                maze[xx][yy] = 1;        //回溯 
            }
        }
    }
}


int main()
{
    while(~scanf("%d%d", &m, &n), m, n)
    {
        init();
        for(int i = 0;i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                scanf("%d", &maze[i][j]);
                if(maze[i][j] == 2)
                {
                    bx = i;
                    by = j;
                    maze[i][j] = 0;             //切记 
                }
            }
        }
        dfs(bx, by, step);
        if(min_step <= 10) printf("%d\n", min_step);       //判断是否在十步之内 
        else printf("-1\n");
    }
    return 0;
}

 

 

posted on 2012-09-02 20:41  有间博客  阅读(212)  评论(0编辑  收藏  举报