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

题意:

  题目很复杂,直接抽象化解释了。给你一个w * h的矩形格子,其中有包含一个数字“2”和一个数字“3”,剩下的格子由“0”和“1”组成,目的是计算从“2”走到“3”的最短步数,“1”代表障碍物,“0”代表可以通行。“2”可以往周围四个方向走,如果往某一个方向走,那么停下来的条件是,当这个方向上存在障碍物“1”,且会停在这个障碍物的前一个格子,并会击碎这个障碍物;如果选择的方向上没有障碍物“1”也没有终点“3”,那么就会一直运动下去,直到出界。如果遇到“3”,那么就算一种到达终点的方法。每选择往一个方向运动,就算一步。如果不能到达或者到达的步数大于10,那么就算失败,输出-1.

拿题目给的图再说明下吧~

图a:球可以往上和右运动,往上运动直到遇到障碍物才会停下,如果没有障碍物就会出界;往右运动,走一个格子后就会遇到障碍物,此时球停在第二行第三列,且第二行第四列的障碍物被击碎,变为空白格,即“0”。不能往下运动,因为与球相邻的就存在障碍物“1”,球至少运动一个格子才会击碎阻碍它的障碍物。

图b:球如果往右运动的话,会停在第二行第二列的位置,且第二行第三列的障碍物会被击碎变为空白格。

图c:球可以往上,左,右运动,往上和左会出界,往右会停在第二行第三列的位置,且第二行第四列的障碍物会被击碎。

思路:

  求最短步数首先想到的是BFS,无奈BFS无法回溯,即无法恢复之前的状态,所以实现起来过于复杂。然后只好利用DFS了,但是DFS要搜索整个解答树才能找到最优解,好在题目给的限制条件是深度不能大于10,也就是O(410),1e6的时间复杂度,可以满足题意了。剩下的就是模拟了,注意判断题条件就好,具体看代码吧~

代码:

 #include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <string> typedef long long LL;
using namespace std;
const int MAXN = ;
int map[MAXN + ][MAXN + ];
int stepX[] = {-, , , };//四个方向:上、下、左、右
int stepY[] = {, , -, };
int ans;//最短步数
int w, h;//w 为宽度(y) ,h为高度(x),注意下
int stX, stY, edX, edY;//开始时“2”的位置和“3”的位置坐标 int check(int x, int y) {//返回 非2 代表可以往这个方向走 返回 非1 代表会停下来
if(map[x][y] == || map[x][y] == ) return ;
else if(map[x][y] == - || map[x][y] == ) return ;//出界或者有障碍物
else return ;
} void backtrack(int x, int y, int t) {
if(x == edX && y == edY || t > ) {//到达终点或者深度大于10
ans = (t < ans ? t : ans);//更新最短步数
}
else {
for(int i = ; i < ; i++) {//往四个方向试探
int tx = x, ty = y;
if(check(tx + stepX[i], y + stepY[i]) != ) { //可以往当前方向运动
while(check(tx + stepX[i], ty + stepY[i]) == ) { //没有障碍物 或 未到达终点的话就一直运动下去
tx += stepX[i], ty += stepY[i];
}
if(map[tx + stepX[i]][ty + stepY[i]] == ) {//遇到障碍物停止运动
map[tx + stepX[i]][ty + stepY[i]] = ;//击碎障碍物
t++; //步数加1
backtrack(tx, ty, t);//继续从障碍物前一个格子开始走
--t; //回溯时恢复现场
map[tx + stepX[i]][ty + stepY[i]] = ;
}
else if(map[tx + stepX[i]][ty + stepY[i]] == ) {//遇到终点停止运动
t++;
backtrack(tx + stepX[i], ty + stepY[i], t);
--t;
}
}
}
}
} int main() {
while(scanf("%d%d", &w, &h), w || h ) {
memset(map, -, sizeof(map));
stX = stY = edX = edY = -;
for(int i = ; i <= h; i++) {
for(int j = ; j <= w; j++) {
scanf("%d", &map[i][j]);
if(map[i][j] == ) stX = i, stY = j; //起点
else if(map[i][j] == ) edX = i, edY = j;//终点
}
}
ans = MAXN;
backtrack(stX, stY, );
printf("%d\n", ans > ? - : ans);
}
return ;
}

POJ 3009 Curling 2.0(DFS + 模拟)的更多相关文章

  1. poj 3009 Curling 2.0( dfs )

    题目:http://poj.org/problem?id=3009 参考博客:http://www.cnblogs.com/LK1994/ #include <iostream> #inc ...

  2. POJ 3009 Curling 2.0【带回溯DFS】

    POJ 3009 题意: 给出一个w*h的地图,其中0代表空地,1代表障碍物,2代表起点,3代表终点,每次行动可以走多个方格,每次只能向附近一格不是障碍物的方向行动,直到碰到障碍物才停下来,此时障碍物 ...

  3. poj 3009 Curling 2.0 (dfs )

    Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11879   Accepted: 5028 Desc ...

  4. 【POJ】3009 Curling 2.0 ——DFS

    Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11432   Accepted: 4831 Desc ...

  5. POJ 3009 Curling 2.0 {深度优先搜索}

    原题 $On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules ...

  6. POJ 3009 Curling 2.0 回溯,dfs 难度:0

    http://poj.org/problem?id=3009 如果目前起点紧挨着终点,可以直接向终点滚(终点不算障碍) #include <cstdio> #include <cst ...

  7. poj 3009 Curling 2.0

    题目来源:http://poj.org/problem?id=3009 一道深搜题目,与一般搜索不同的是,目标得一直往一个方向走,直到出界或者遇到阻碍才换方向. 1 #include<iostr ...

  8. 【原创】poj ----- 3009 curling 2 解题报告

    题目地址: http://poj.org/problem?id=3009 题目内容: Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Tot ...

  9. POJ3009——Curling 2.0(DFS)

    Curling 2.0 DescriptionOn Planet MM-21, after their Olympic games this year, curling is getting popu ...

随机推荐

  1. 【uoj3】 NOI2014—魔法森林

    http://uoj.ac/problem/3 (题目链接) 题意 给出一张带权图,每条边有两个权值A和B,一条路径的花费为路径中的最大的A和最大的B之和.求从1走到n的最小花费. Solution ...

  2. Python 进程间的通信

    #-*-coding:utf-8-*- '''python提供了多种进程间的通信方式,如:Queue,Pipe,Valie+Array等. Queue与Pipe的区别在于Pipe常用来在两个进程间通信 ...

  3. sadpairs

    #include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using ...

  4. DNS ------ windows执行DNS过程

    前言 TCP/IP协议是网络通讯的基础,平常在对TCP/IP协议设置时会涉及到IP地址,子网掩码,默认网关和DNS这几个参数.这里我们主要谈下IP地址和DNS这两个参数之间的关系. 首先计算机在网络中 ...

  5. linux sed文本

    sed介绍 sed(stream editor)是一种非交互式的流编辑器,通过多种转换修改流经它的文本.默认情况下,sed不会改变原文件本身,而只是对流经sed命令的文本进行修改,并将修改后的结果打印 ...

  6. 写一个栈,实现出栈、入栈、求最小值,时间复杂度为O(1)

    #-*-coding:utf-8-*- ''' 需求:写一个栈,实现出栈.入栈.求最小值,时间复杂度为O(1) 思路:通过两个栈实现,一个栈stack,一个辅助栈min_stack,记录stack中的 ...

  7. sql的执行流程

    mysql中的SQL语句执行是有一定顺序的,如下:1. from2. on3. join4. where5. group by6. with7. having8. select9. distinct1 ...

  8. angularJs实现级联操作

    angular实现级联非常的方便比起传统的jq和js来说,一般我们肯定是从后台获取一个list,然后生成一个下拉框,然后选中一个下拉框,得到id,再得到下一个list. 这些angular都给我做好了 ...

  9. git安装与初始化

    命令行 Git有多重方式使用 原生命令行,才能使用git所有命令,会git命令再去用gui图形工具,完全无压力 GUI图形软件,只是实现了git的部分功能,以减免操作难度,难以记住git原生命令 不同 ...

  10. SQL语句(八)按条件查询

    SELECT * FROM student SELECT sclass, snumb, sname FROM student --物理班有哪些同学 --年龄小于20岁的有哪些同学? --定价在30元以 ...