poj3009 Curling 2.0(dfs水题)

题目链接:http://poj.org/problem?id=3009

题目大意很简单,模拟一个冰壶比赛,给定的规则比较多,求冰壶从起点滑到终点的最少敲击次数。

规则细节如下:每次敲击冰壶后冰壶会沿一条直线滑动直到撞到障碍物(地图上的1),敲击次数不

能超过10;冰壶不能滑出给定比赛区域;如果冰壶的某个方向和障碍物直接相邻则不能往此方向移动;

如果不能到达指定地点输出-1.细节比较多,练习代码能力(代码一定要写清晰,不然不好找bug)以

及bfs的好题。其中需要注意的是冰壶到达每个点可能来自不同的方向,借助障碍物进行转换方向,所

以不能标记每个点的状态是否被访问过来判断是否dfs;还有就是再回溯的过程中要注意,冰壶如果滑

向障碍物则会停在障碍物的前一格,如果滑向终点(地图上的3)则停在终点位置,回溯的过程中不能

直接将地图更改为障碍物,而要判断是不是终点(判断3或1)。

AC代码:

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
using namespace std;
#define oo 0x3f3f3f3f
int maps[30][30], m, n, ans;
int dir[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
bool check(int x, int y, int index)
{
    if(x+dir[index][0]<1 || x+dir[index][0]>m)
        return false;

    if(y+dir[index][1]<1 || y+dir[index][1]>n)
        return false;

    if(maps[ x+dir[index][0] ][ y+dir[index][1] ] == 1)
        return false;
    int disx = 0, disy = 0;
    for(int i=1; ; i++)
    {
        disx += dir[index][0];
        disy += dir[index][1];

        if(x+disx<1 || x+disx>m)
            return false;
        if(y+disy<1 || y+disy>n)
            return false;

        if(maps[x+disx][y+disy]==1 || maps[x+disx][y+disy]==3)
            return true;
    }
}
void change(int *x, int *y, int int_x, int int_y, int index)
{
    int disx = 0, disy = 0;
    for(int i=1; ; i++)
    {
        disx += dir[index][0];
        disy += dir[index][1];
        if(maps[int_x+disx][int_y+disy]==1)
        {
            *x = int_x+disx-dir[index][0];
            *y = int_y+disy-dir[index][1];
            break;
        }
        if(maps[int_x+disx][int_y+disy]==3)
        {
            *x = int_x+disx;
            *y = int_y+disy;
            break;
        }
    }
}
void dfs(int x, int y, int step)
{
    if(step>10 || step>=ans)
        return ;
    if(maps[x][y] == 3)
    {
        ans = min(ans, step);
        return ;
    }

    for(int i=0; i<4; i++)
    {
        if(check(x, y, i))
        {
            int nx, ny;
            change(&nx, &ny, x, y, i);
            if(maps[nx][ny] != 3)
                maps[nx+dir[i][0]][ny+dir[i][1]] = 0;
            dfs(nx, ny, step+1);
            if(maps[nx][ny] != 3)
                maps[nx+dir[i][0]][ny+dir[i][1]] = 1;

        }
    }
}
int main()
{
    int sx, sy;
    while(scanf("%d %d", &n, &m), m||n)
    {
        for(int i=1; i<=m; i++)
            for(int j=1; j<=n; j++)
            {
                scanf("%d", &maps[i][j]);
                if(maps[i][j] == 2)
                {
                    sx = i;
                    sy = j;
                }
            }

        ans = oo;
        dfs(sx, sy, 0);
        if(ans == oo)
            ans = -1;
        printf("%d\n", ans);
    }
    return 0;
}

 

posted on 2017-07-18 17:27  刘威O_0  阅读(158)  评论(0)    收藏  举报

导航