Hdu 2364 Escape

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;
}
时间: 2024-10-22 06:56:50

Hdu 2364 Escape的相关文章

HDU 1733 Escape(分层网络流)

HDU 1733 Escape 题目链接 题意:给定一个图,#是墙,@是出口,.可以行走,X是人,每个时间每个格子只能站一个人,问最少需要多少时间能让人全部撤离(从出口出去) 思路:网络流,把每个结点每秒当成一个结点,这样枚举时间,每多一秒就在原来的网络上直接加一层继续增广即可,注意考虑方向的时候,要考虑上原地不动 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorit

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

hdu 3605 Escape (二分图多重匹配)

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4298    Accepted Submission(s): 1129 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient

HDU 3605 Escape(最大流+缩点转换)

http://acm.hdu.edu.cn/showproblem.php?pid=3605 题目很简单,要求的就是最后能搬到星球上去的人的个数.刚开始看到,知道是最大流,就把人和星球都设为点,能生存就连线,权值为1,最后建立超级源点和超级汇点.求出最大流量即可.先是RE,开大数组后TLE.仔细算了,光光人到星球的便就可达到100w了,超时的概率太大了.后来找了解题报告,知道了缩点这一说,因为星球个数m最大只有10个,所以每个人最多只有1024种情况,把这每一种情况设为点(这里很抽象),将之与符

HDU 3036 Escape 网格图多人逃生 网络流||二分匹配 建图技巧

前言 在编程过程中总结归纳出来的一种编程经验,从而形成的设计思想称为设计模式. 设计模式有23种.它适用于所有的编程语言. 常用的有创新型的设计模式:简单工厂.抽象工厂和单例模式:行为型的设计模式:模板设计模式.观察者模式和命令模式:结构性的设计模式:适配器设计模式.代理模式(静态和动态两种,典型的有在spring的AOP编程中使用)和装饰器设计模式. 正文 单例模式(singleton) 保证一个类在内存中只能创建一个实例. 1.实现步骤: 1)将构造器私有化,即使用private修饰构造器

Hdu 3605 Escape (最大流 + 缩点)

题目链接: Hdu 3605  Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是TLE还是稳稳的.以前只遇到过网络流拆点建图,这个正好是缩点建图.吼吼吼~~~,建图的方式还是值得学习的. 因为星球数目最多十个,那么无论有多少个人,其不同选择也就2^10种咯.把不同的选择作为节点,节点就从10^5减少到了2^10,整整缩小了一个数量级呢.建立源点和汇点,源点和选择链接,边权为这种选

【HDOJ】2364 Escape

bfs.题目做的不细心,好多小错误.尤其注意起始点就是边界的情况.wa了八次. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 85 8 9 typedef struct node_st { 10 int x, y; 11 int d, s; 12 node_st(

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 8001    Accepted Submission(s): 1758 Problem Description 2012 If this is the end of th

HDU 3605 Escape 最大流+状压

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7145    Accepted Submission(s): 1553 Problem Description 2012 If this is the end of the