POJ3009 Curling 2.0【DFS】

题目链接:

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;
}
时间: 2024-10-01 04:29:20

POJ3009 Curling 2.0【DFS】的相关文章

poj 3009 Curling 2.0 【DFS】

题意:从2出发,要到达3, 0可以通过,碰到1要停止,并且1处要变成0, 并且从起点开始沿着一个方向要一直前进,直至碰到1(或者3)处才能停止,(就是反射来反射去知道反射经过3).如果反射10次还不能到达3,就输出-1. 策略:深搜. 易错点,方向不容易掌握,并且,出题人把n, m顺序反了. 代码: #include<stdio.h> #include<string.h> int map[25][25]; int ans, n, m; const int dir[4][2] = {

poj3009 Curling 2.0 (DFS按直线算步骤)

Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14563   Accepted: 6080 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is

【DFS】【拓扑排序】【动态规划】Gym - 100642A - Babs&#39; Box Boutique

给你10个箱子,有长宽高,每个箱子你可以决定哪个面朝上摆.把它们摞在一起,边必须平行,上面的不能突出来,问你最多摆几个箱子. 3^10枚举箱子用哪个面.然后按长为第一关键字,宽为第二关键字,从大到小排序. 如果前面的宽大于等于后面的宽,就连接一条边. 形成一张DAG,拓扑排序后跑最长路即可. #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespa

NYOJ 587 blockhouses 【DFS】

blockhouses 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. A blockhouse is a small castle th

NYOJ 722 数独 【DFS】+【预处理】

数独 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 数独是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个3*3宫内的数字均含1-9,不重复. 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的. 有一天hrdv碰到了一道号称是世界上最难的数独的题目,作为一名合格的程序员,哪能随随便便向困难低头,于是他决定编个程序来解决它.. 输入 第一行有一个

poj 1011 Sticks 【DFS】+【剪枝】

题意:有未知根(长度一样)木棒(小于等于n),被猪脚任意的截成n段,猪脚(脑抽了)想知道被截之前的最短长度(我推测猪脚得了健忘症). 这道题光理解题意就花了好久,大意就是任意根被截后的木棒拼到一起,能不能组成s(<=n)根的相同的木棒, 例:数据 9  5 1 2 5 1 2 5 1 2 可以组成最短为6 的(5+1, 2+2+2)3根木棒. 策略:深搜. 不过要是传统的深搜的话,TLE妥妥的.所以要剪枝(所谓剪枝,就是多加几个限制条件). 话不多说直接上代码. 代码1: #include <

HDU1010 Tempter of the Bone 【DFS】+【剪枝】

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 70895    Accepted Submission(s): 19535 Problem Description The doggie found a bone in an ancient maze, which fascinated him a

nyoj 325 zb的生日 【DP】||【DFS】

两种方法: 第一种:将总数一半当做背包,用总数-2*最多能装的数目就是所求: 第二种:深搜: zb的生日 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 今天是阴历七月初五,acm队员zb的生日.zb正在和C小加.never在武汉集训.他想给这两位兄弟买点什么庆祝生日,经过调查,zb发现C小加和never都很喜欢吃西瓜,而且一吃就是一堆的那种,zb立刻下定决心买了一堆西瓜.当他准备把西瓜送给C小加和never的时候,遇到了一个难题,never和C小加不在一块住,只能

【dfs】hdu 1016 Prime Ring Problem

[dfs]hdu 1016 Prime Ring Problem 题目链接 刚开始接触搜索,先来一道基本题目练练手. 注意对树的深度进行dfs dfs过程中注意回退!!! 素数提前打表判断快一些 参考代码 /*Author:Hacker_vision*/ #include<bits/stdc++.h> #define clr(k,v) memset(k,v,sizeof(k)) using namespace std; const int _max=1e3+10;//素数打表 int n,pr