Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=2364

这道题的特殊之处在于能转弯时不能直走,必须转弯,所以在行走时,要判断能否转弯,不能转弯时才选择直走。

因为是一道走迷宫的题,所以可以用BFS解决问题。

有一点需要注意:起点也有可能是终点,所以在判断是否到终点时,最好判断该点是不是'#',而不该判断是不是'.',因为终点有可能是'@'

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue> using namespace std; const int NEVERCOME = -1;
const int NORTH = 0;
const int SOUTH = 2;
const int WEST = 1;
const int EAST = 3; const int MAXN = 80 + 5;
int vis[MAXN][MAXN][5]; // the first param means x, the second one means y
// the third one means dir
char maze[MAXN][MAXN]; // record the maze
int moveToDir[4][2]; int Bfs( int height, int width, int startX, int startY );
bool isEnd( int &height, int &width, int &x, int &y ); // judge whether the person has reached the end point
bool isInside( int &height, int &width, int &x, int &y ); // judge whether the person has reached the end point int main()
{
// dir
moveToDir[NORTH][0] = -1;
moveToDir[NORTH][1] = 0; moveToDir[SOUTH][0] = 1;
moveToDir[SOUTH][1] = 0; moveToDir[WEST][0] = 0;
moveToDir[WEST][1] = -1; moveToDir[EAST][0] = 0;
moveToDir[EAST][1] = 1; int T;
cin >> T;
int height, width;
int i, j;
int startX, startY;
while( T-- ) {
scanf( "%d%d", &height, &width );
for( i=0; i<height; i++ ) {
getchar();
for( j=0; j<width; j++ ) {
scanf( "%c", &maze[i][j] );
if( maze[i][j]=='@' ) {
startX = i;
startY = j;
}
//printf( "%c", maze[i][j] );
}
//printf("\n");
}
printf( "%d\n", Bfs( height, width, startX, startY ) );
}
return 0;
} typedef struct Node{
int x, y;
int step;
int dir; // means the dir the person facing
}Node; int Bfs( int height, int width, int startX, int startY ) {
queue <Node> q;
Node t, next;
t.x = startX;
t.y = startY;
t.step = 0; memset( vis, NEVERCOME, sizeof(vis) );
int i, j;
// the four directions
t.dir = NORTH;
vis[t.x][t.y][t.dir] = 0;
q.push( t ); t.dir = SOUTH;
vis[t.x][t.y][t.dir] = 0;
q.push( t ); t.dir = WEST;
vis[t.x][t.y][t.dir] = 0;
q.push( t ); t.dir = EAST;
vis[t.x][t.y][t.dir] = 0;
q.push( t ); while( !q.empty() ) {
t = q.front();
q.pop(); if( isEnd( height, width, t.x, t.y ) ) {
return t.step;
}
int i;
bool flag = false;
// can the person go left or right
for( i=0; i<4;i++ ) {
if( (i&1) != ( t.dir&1 ) ) { // need to turn
next.x = t.x + moveToDir[i][0];
next.y = t.y + moveToDir[i][1];
next.step = t.step + 1;
next.dir = i; if( isInside( height, width, next.x, next.y ) ) {
flag = true;
if( vis[next.x][next.y][next.dir]==-1 || next.step<vis[next.x][next.y][next.dir] ) {
q.push(next);
vis[next.x][next.y][next.dir] = next.step;
}
}
}
} // should go straight ?
if( flag == false ) {
next.x = t.x + moveToDir[t.dir][0];
next.y = t.y + moveToDir[t.dir][1];
next.step = t.step + 1;
next.dir = t.dir; if( isInside( height, width, next.x, next.y ) ) {
if( vis[next.x][next.y][next.dir]==-1 || next.step<vis[next.x][next.y][next.dir] ) {
q.push(next);
vis[next.x][next.y][next.dir] = next.step;
}
} }
} return -1;
} bool isEnd( int &height, int &width, int &x, int &y ) {
if( maze[x][y] != '#' ) {
if( ( x==0 || x==height-1 ) || ( y==0 || y==width-1) ) {
return true;
}
}
return false;
} bool isInside( int &height, int &width, int &x, int &y ) {
if( maze[x][y] == '.' ) {
if( x>=0 && x<height && y>=0 && y<width ) {
return true;
}
}
return false;
}

Hdu 2364 Escape的更多相关文章

  1. hdu 2364 Escape【模拟优先队列】【bfs】

    题目链接:https://vjudge.net/contest/184966#problem/A 题目大意: 走迷宫.从某个方向进入某点,优先走左或是右.如果左右都走不通,再考虑向前.绝对不能往后走, ...

  2. HDU 3533 Escape(大逃亡)

    HDU 3533 Escape(大逃亡) /K (Java/Others)   Problem Description - 题目描述 The students of the HEU are maneu ...

  3. HDU 3605 Escape (网络流,最大流,位运算压缩)

    HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...

  4. Hdu 3605 Escape (最大流 + 缩点)

    题目链接: Hdu 3605  Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...

  5. HDU 3605 Escape(状压+最大流)

    Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Sub ...

  6. HDU 2364 (记忆化BFS搜索)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2364 题目大意:走迷宫.从某个方向进入某点,优先走左或是右.如果左右都走不通,再考虑向前.绝对不能往 ...

  7. HDU 3605 Escape 最大流+状压

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others)    ...

  8. hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    ...

  9. HDU 3533 Escape bfs 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=3533 一道普通的bfs,但是由于代码实现出了bug还是拖了很久甚至对拍了 需要注意的是: 1.人不能经过炮台 2 ...

随机推荐

  1. Asp.net 提供程序模型

    需要说明一下几点 1.什么是提供程序? 2.ASP.NET 4.5 中的提供程序 3.配置提供程序 有一下几种存储状态的方式 1.应用程序状态 2.会话状态 3.高速缓存状态 4.cookie 5.查 ...

  2. POJ 2142:The Balance_扩展欧几里得(多组解)

    先做出两个函数的图像,然后求|x|+|y|的最小值.|x|+|y|=|x0+b/d *t |+|y0-a/d *t| 这个关于t的函数的最小值应该在t零点附近(在斜率大的那条折线的零点附近,可以观察出 ...

  3. asp.net中实现MD5加密、解密的方法

    这个MD5加密.解密的方法会使用即可. 使用时的代码备忘:Response.Write(FormsAuthentication.HashPasswordForStoringInConfigFile(& ...

  4. iOS实战(零):开发社区、文档等资源

    社区 Apple官方资源 Xcode文档库: Window->Documentation and API Reference (可以在xcode的Preferences中下载最新的文档) iOS ...

  5. Android应用开发实例篇(1)-----简易涂鸦板

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378328.html 一.概述 这次要做一个简单的涂鸦板应用,以前在Qt上实现过,突然想 ...

  6. C++的常量折叠(三)

    背景知识 在开始之前先说一下符号表,这个编译器中的东西.下面看一下百度百科中的描述: 符号表是一种用于语言翻译器中的数据结构.在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如 ...

  7. Hadoop学习笔记(4)hadoop集群模式安装

    具体的过程参见伪分布模式的安装,集群模式的安装和伪分布模式的安装基本一样,只有细微的差别,写在下面: 修改masers和slavers文件: 在hadoop/conf文件夹中的配置文件中有两个文件ma ...

  8. maven安装scala插件

    默认情况maven不支持scala 所以需要安装maven-scala插件 更新地址:http://alchim31.free.fr/m2e-scala/update-site/ (m2eclipse ...

  9. The Standard Librarian: I/O and Function Objects: Containers of Pointers

    C++ Experts Forum The Standard Librarian: I/O and Function Objects: Containers of Pointers Matthew A ...

  10. LintCode- 删除排序数组中的重复数字

    题目描述: 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 样例 给出数组A =[1,1 ...