Finding Nemo_BFS

Description

Nemo is a naughty boy. One day he went into the deep sea all by himself. Unfortunately, he became lost and couldn‘t find his way home. Therefore, he sent a signal to his father, Marlin, to ask for help. 
After checking the map, Marlin found that the sea is like a labyrinth with walls and doors. All the walls are parallel to the X-axis or to the Y-axis. The thickness of the walls are assumed to be zero. 
All the doors are opened on the walls and have a length of 1. Marlin cannot go through a wall unless there is a door on the wall. Because going through a door is dangerous (there may be some virulent medusas near the doors), Marlin wants to go through as few doors as he could to find Nemo. 
Figure-1 shows an example of the labyrinth and the path Marlin went through to find Nemo. 

We assume Marlin‘s initial position is at (0, 0). Given the position of Nemo and the configuration of walls and doors, please write a program to calculate the minimum number of doors Marlin has to go through in order to reach Nemo.

Input

The input consists of several test cases. Each test case is started by two non-negative integers M and N. M represents the number of walls in the labyrinth and N represents the number of doors. 
Then follow M lines, each containing four integers that describe a wall in the following format: 
x y d t 
(x, y) indicates the lower-left point of the wall, d is the direction of the wall -- 0 means it‘s parallel to the X-axis and 1 means that it‘s parallel to the Y-axis, and t gives the length of the wall. 
The coordinates of two ends of any wall will be in the range of [1,199]. 
Then there are N lines that give the description of the doors: 
x y d 
x, y, d have the same meaning as the walls. As the doors have fixed length of 1, t is omitted. 
The last line of each case contains two positive float numbers: 
f1 f2 
(f1, f2) gives the position of Nemo. And it will not lie within any wall or door. 
A test case of M = -1 and N = -1 indicates the end of input, and should not be processed.

Output

For each test case, in a separate line, please output the minimum number of doors Marlin has to go through in order to rescue his son. If he can‘t reach Nemo, output -1.

Sample Input

8 9
1 1 1 3
2 1 1 3
3 1 1 3
4 1 1 3
1 1 0 3
1 2 0 3
1 3 0 3
1 4 0 3
2 1 1
2 2 1
2 3 1
3 1 1
3 2 1
3 3 1
1 2 0
3 3 0
4 3 1
1.5 1.5
4 0
1 1 0 1
1 1 1 1
2 1 1 1
1 2 0 1
1.5 1.7
-1 -1

Sample Output

5
-1

【题意】给出n,m分别表示墙数和门数

再给出n组x,y,op,t;op=1时表示起点为x,y的墙向上t个单位,op=0则表示起点为x,y的墙向右t个单位

再给出m组x,y,op;op=1时表示起点为x,y的门向上1个单位,op=0则表示起点为x,y的门向右1个单位

给出sx,sy;求从(1,1)到(sx,sy)最少经过的门

【思路】用xa记录(i,j)的格子的上面的边的状态,ya记录(i,j)的格子的右面的边的状态。进行bfs;

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=210;
int xa[N][N],ya[N][N];//xa记录(i,j)的格子的上面的边的状态,ya记录(i,j)的格子的右面的边的状态//用inf表示墙,0表示空,1表示门;
int dis[N][N];
int di[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int n,m;
int wall=inf;
int maxx,maxy;
int get_val(int x,int y,int op)//检验一下有没有穿越门
{
    if(op==0) return ya[x][y];向右,检测当前格子的右边的值
    else if(op==1) return ya[x-1][y];//向左,检测左边的格子的右边值
    else if(op==2) return xa[x][y];//向上,检测当前格子的上边值
    else return xa[x][y-1];//向下,检测下面格子的上边值
}
bool go(int x,int y)//检测是否在范围内
{
    if(x<1||x>maxx||y<1||y>maxy) return false;
    else return true;
}
int bfs(int sx,int sy)
{
    queue<int>qu;
    for(int i=0;i<=maxx;i++)
    {
        for(int j=0;j<=maxy;j++)
        {
            dis[i][j]=inf;
        }
    }
    dis[1][1]=0;//从(1,1)这个格子出发
    qu.push(1);//横纵坐标都入队
    qu.push(1);
    while(!qu.empty())
    {
        int nowx=qu.front();qu.pop();
        int nowy=qu.front();qu.pop();
        for(int i=0;i<4;i++)//向四个方向查找
        {
            int xx=nowx+di[i][0];
            int yy=nowy+di[i][1];
            int tmp=get_val(nowx,nowy,i);
            if(go(xx,yy)&&dis[xx][yy]>dis[nowx][nowy]+tmp)//在范围内,并经过的门少,则入队
            {
                dis[xx][yy]=dis[nowx][nowy]+tmp;
                qu.push(xx);
                qu.push(yy);
            }
        }
    }
    return dis[sx][sy]==inf?-1:dis[sx][sy];//inf表示此路不通,无路可走
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        if(m==-1&&n==-1) break;
        memset(xa,0,sizeof(xa));
        memset(ya,0,sizeof(ya));
        maxx=-1,maxy=-1;
        for(int i=1; i<=n; i++)
        {
            int x,y,op,t;
            scanf("%d%d%d%d",&x,&y,&op,&t);
            if(op)
            {
                for(int j=0; j<t; j++)
                    ya[x][y+j+1]=wall;
                maxx=max(maxx,x+1);
                maxy=max(maxy,y+t+1);

            }
            else
            {
                for(int j=0;j<t;j++)
                {
                    xa[x+j+1][y]=wall;
                }
                maxx=max(maxx,x+t+1);
                maxy=max(maxy,y+1);
            }
        }
        for(int i=1;i<=m;i++)
        {
            int x,y,op;
            scanf("%d%d%d",&x,&y,&op);
            if(op)
            {
                ya[x][y+1]=1;
            }
            else xa[x+1][y]=1;
        }
        double sx,sy;
        scanf("%lf%lf",&sx,&sy);
        if(sx<1||sx>199||sy<1||sy>199) printf("0\n");
        else printf("%d\n",bfs((int)sx+1,(int)sy+1));
    }
    return 0;
}
时间: 2024-10-01 15:41:20

Finding Nemo_BFS的相关文章

POJ 2049 Finding Nemo 优先队列 STL

题目链接:http://poj.org/problem?id=2049 题目利用了<海底总动员>的情节,小丑鱼尼莫迷路了,他老爸去营救他便是题意. 题目给出了这样的地图,说是假设地图由墙和门组成,忽略墙的厚度,地图上有门,没有墙的地方是可以自由行动的问可以经过最少多少道门便可以营救到尼莫. 这个题给的数据是墙的交点为整数点,但鱼爸爸实在非墙的地方自由移动. 因此,这个题有两个难点: 1.如果建图保存地图 2.如何在地图上遍历 由于题目是给出一个点(x,y),来表示一段墙 我便用一对X,Y来表示

Finding Lines

Finding Lines 题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4967 概率 在听题解前毫无头绪,题解帮我打开了新世界的大门: 随机取一个点在答案直线(如果存在这个直线)上的概率是p%, 那么随机取到两个点构成的直线就是答案直线的概率是p%*p%: 也就是说,随机取到两个点构成的直线不是答案直线的概率为

基于分治法的找秩(maxium rank finding)策略

rank finding 问题的概述如下: 在一群离散的点中,检查对于每个点,是否有x值和y值都小于它的点,若有,则该点的秩为这些小于它的点的数量. 分治法思想: 以界面上所有点中x值的中位数为基准,递归地把目标区域分成两部分,直到每个区域中的点在一个以下,对于每一个细小的区域,检查其left child区域中的点的y值和right child区域中的点的y值,以对right child中的点的秩进行统计. 该方法通过分治排除了水平位置不符合标准的点,有效的减少了统计次数. 代码示例如下: #i

Finding Action Tubes - cvpr - 2015

论文题目Finding Action Tubes, 论文链接 该篇论文是CVPR 2015的, 主要讲述了action tube的localization. 直接看图说话, 该论文的核心思想/步骤可以分为两个components: 1 Action detection at every frame of the video 2 Linked detection in time produce action tubes 下面就分开来说每个component. 1 Action detection

随机算法 - HNU 13348 Finding Lines

Finding Lines Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13348&courseid=0 Mean: 给你平面上1e5个点,让你判断是否可以找到一条直线,使得p%的点都在这条直线上. analyse: 经典的随机算法题. 每次随机出两个点,然后对n个点进行判断,看是否有p%的点在这条直线上. 关于随机算法正确性的证明: 每次随机一个点,这个点在直线上的概率是p,p最小为2

hdu1937 Finding Seats

hdu1937 Finding Seats 题意是 求最小的矩形覆盖面积内包含 k 个 空位置 枚举上下边界然后 双端队列 求 最小面积 #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <map> #include <que

HDU 4889 Scary Path Finding Algorithm

题意: 构造一幅图  使题中给出的程序按该图执行  最终变量doge大于输入的C跳出 思路: 出题人思维简直神了!  实在是膜拜!  借题解的图: 按照图中所画  可以继续向右延伸 为何这样可以??  为何边权要这么取?? 先回答第二个问题: 取负数是为了可以不断的去更新  例如如果走了上面的-4那条边  那么它右边的所有点就又可以再更新一次  这样使更新达到了指数级别 (其实可以把所有的值加上一个值K  不过这个K一定要取好!) 除了负数外我们发现数字都是2的几次幂  如果我们按2进制来考虑的

Method for finding shortest path to destination in traffic network using Dijkstra algorithm or Floyd-warshall algorithm

A method is presented for finding a shortest path from a starting place to a destination place in a traffic network including one or more turn restrictions, one or more U-turns and one or more P-turns using a Dijkstra algorithm. The method as sets a

LightOJ - 1215 Finding LCM

Finding LCM 已知a, b, c的最小公倍数为L, 给你a,b,问你是否存在最小的c满足题意,不存在输出impossible 素数分解 1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define INF 0x3f3f3f3f 6 #define MOD 1000000007 7 using namespace std; 8