poj 2049

Finding Nemo

Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 7373   Accepted: 1715

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 6
1 2 1 5
0 2 0
0 3 0
0 4 0
0 5 0
0 6 0
0 7 0
0.5 5.5
4 1
3 2 1 1
1 3 0 2
1 1 0 2
1 1 1 2
2 1 1
1.5 1.5
-1 -1

Sample Output

5
-1
2
0
题目意思很清晰了,直接上AC代码了,里面解释很清楚
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define MM 210
#define MX 9999999
struct Node{
    int x,y,dis;
    friend bool operator <(const Node &a,const Node &b){
        return a.dis>b.dis;                                 //注意这里是>,因为优先队列是大顶堆结构
    }
    Node(int X,int Y,int DIS){
        x=X; y=Y; dis=DIS;
    }
};
int xe[MM][MM],ye[MM][MM];             //xe表示横向边  ye表示纵向边
int dis[MM][MM];                       //表示到 0 0的距离
int f_x,f_y;
priority_queue <Node> q;               //优先队列
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int M,N;
    while(scanf("%d%d",&M,&N)!=EOF&&(M!=-1 || N!=-1)){
        memset(xe,0,sizeof(xe));
        memset(ye,0,sizeof(ye));
        int x,y,d,t;
        int mx,my;
        mx=my=0;
        for(int i=0;i<M;i++){                    //初始化墙
            scanf("%d%d%d%d",&x,&y,&d,&t);
            if(d==1){
                for(int j=0;j<t;j++)
                    ye[x][y+j]=MX;               //ye[x][y]表示 x y+1这条边
                mx=max(mx,x);
                my=max(my,y+t);
            }
            else{
                for(int j=0;j<t;j++)
                    xe[x+j][y]=MX;
                mx=max(mx,x);
                my=max(my,y+t);
            }
        }

        for(int i=0;i<N;i++){                     //初始化门
            scanf("%d%d%d",&x,&y,&d);
            if(d==1){
                ye[x][y]=1;
                mx=max(mx,x);
                my=max(my,y+1);
            }
            else{
                xe[x][y]=1;
                mx=max(mx,x+1);
                my=max(my,y);
            }
        }
        float xd,yd; scanf("%f%f",&xd,&yd);
        if(xd>mx || yd>my){
            printf("0\n");
            continue;
        }

        f_x=(int)xd; f_y=(int)yd;
        for(int i=0;i<=mx;i++)
            for(int j=0;j<=my;j++)
                dis[i][j]=MX;
        dis[0][0]=0;
        int tmp_x,tmp_y;
        int flag=0;
        while(!q.empty())
            q.pop();
        q.push(Node(0,0,0));
        while(!q.empty()){                         //从0 0出发bfs直到到达目的地
            tmp_x=q.top().x;  tmp_y=q.top().y;
            q.pop();
            if(tmp_x==f_x && tmp_y==f_y){          //到达目的地,退出
                flag=1;
                break;
            }
            if(tmp_y+1<=my && dis[tmp_x][tmp_y+1]>dis[tmp_x][tmp_y]+xe[tmp_x][tmp_y+1]){   //向上走
                dis[tmp_x][tmp_y+1]=dis[tmp_x][tmp_y]+xe[tmp_x][tmp_y+1];
                q.push(Node(tmp_x,tmp_y+1,dis[tmp_x][tmp_y+1]));
            }
            if(tmp_x+1<=mx && dis[tmp_x+1][tmp_y]>dis[tmp_x][tmp_y]+ye[tmp_x+1][tmp_y]){    //向右走
                dis[tmp_x+1][tmp_y]=dis[tmp_x][tmp_y]+ye[tmp_x+1][tmp_y];
                q.push(Node(tmp_x+1,tmp_y,dis[tmp_x+1][tmp_y]));
            }
            if(tmp_y-1>=0 && dis[tmp_x][tmp_y-1]>dis[tmp_x][tmp_y]+xe[tmp_x][tmp_y]){        //向下走  注意:好好体会这里的 +xe[tmp_x][tmp_y]
                dis[tmp_x][tmp_y-1]=dis[tmp_x][tmp_y]+xe[tmp_x][tmp_y];                                      //而不是 +xe[tmp_x][tmp_y-1]
                q.push(Node(tmp_x,tmp_y-1,dis[tmp_x][tmp_y-1]));
            }
            if(tmp_x-1>=0 && dis[tmp_x-1][tmp_y]>dis[tmp_x][tmp_y]+ye[tmp_x][tmp_y]){        //向左走  注意:好好体会这里的 +ye[tmp_x][tmp_y]
                dis[tmp_x-1][tmp_y]=dis[tmp_x][tmp_y]+ye[tmp_x][tmp_y];                                      //而不是 +xe[tmp_x][tmp_y-1]
                q.push(Node(tmp_x-1,tmp_y,dis[tmp_x-1][tmp_y]));
            }
        }
        if(flag)
            printf("%d\n",dis[f_x][f_y]);
        else
            printf("-1\n");
    }
    return 0;
}

poj 2049

时间: 2024-10-14 02:34:19

poj 2049的相关文章

POJ 2049 Finding Nemo 优先队列 STL

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

【POJ 2049】Finding Nemo

[POJ 2049]Finding Nemo 迷宫类Bfs,不同于之前的是之前是点 这次是房间,我的做法是把每个房间看做一个点(移动地图使房间为整型坐标 便于用数组下表表示房间坐标) 上下左右是墙/门/无用1 0 -1表示 然后Bfs遍历即可 坑点有x/y<0 和x/y > 199的情况 贡献了好多个RE 上代码 #include <cstdio> #include <cstring> #include <queue> using namespace std

POJ 2049— Finding Nemo(三维BFS)10/200

海底总动员.... 这个题开始不会建图,彻底颠覆以前我对广搜题的想法.想了好久, 忽然想到省赛时HYPO让我做三维BFS来着,一直没做,看到POJ计划这个题,就是三维BFS解题,就做了一下, 对于这个题....实在不知道说什么好,又坑.又SB,POJ的后台数据和题目描述的完全不一样,看了DIscuss之后开始 改动代码,最后改的又臭又长,搜了无数题解找数据,卡了整整两天. 挥挥洒洒 160行....同时也是我第一次使用  三维建图+BFS,纪念一下! 2049 算是我攻克POJ计划的第一个卡两天

POJ 2049 Finding Nemo BFS

题目大意:给你一个奇奇怪怪的迷宫, 这个迷宫包括墙和门.再给你一个起始坐标, 问你从迷宫内到外面至少要穿越多少的门. 题目分析: 穿越多少门等同于路过了多少个格子. 为此我们可以将整个地图中的格子,门,墙,墙的交界处(格子的顶点)全部抽象成点. 即坐标(奇数,奇数)为格子的坐标,坐标(奇数,偶数)或坐标(偶数,奇数)为门或墙的坐标,坐标(偶数,偶数)为格子的顶点. 这样题目就转化成了从起始点所在的格子走到迷宫外的格子最少要经过多少个格子,用step[i][j]表示走出迷宫后遇到的第一个格子的坐标

poj 2049 Let it Bead(polya模板)

Description "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found out that customers are interested in buying colored bracelets.

POJ 2049 Finding Nemo

Finding Nemo Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 8631   Accepted: 2019 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. Therefo

POJ题目分类推荐 (很好很有层次感)

著名题单,最初来源不详.直接来源:http://blog.csdn.net/a1dark/article/details/11714009 OJ上的一些水题(可用来练手和增加自信) (POJ 3299,POJ 2159,POJ 2739,POJ 1083,POJ 2262,POJ 1503,POJ 3006,POJ 2255,POJ 3094) 初期: 一.基本算法: 枚举. (POJ 1753,POJ 2965) 贪心(POJ 1328,POJ 2109,POJ 2586) 递归和分治法. 递

POJ 刷题指南

OJ上的一些水题(可用来练手和增加自信) (POJ 3299,POJ 2159,POJ 2739,POJ 1083,POJ 2262,POJ 1503,POJ 3006,POJ 2255,POJ 3094) 初期: 一.基本算法: 枚举. (POJ 1753,POJ 2965) 贪心(POJ 1328,POJ 2109,POJ 2586) 递归和分治法. 递推. 构造法.(POJ 3295) 模拟法.(POJ 1068,POJ 2632,POJ 1573,POJ 2993,POJ 2996) 二

POJ题目推荐(转载)

POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求,当然有能力的同学可以直接切掉.2.标记为A and B的题目是比较相似的题目,建议大家两个一起做,可以对比总结,且二者算作一个题目.3.列表中大约有70个题目.大家选做其中的50道,且每类题目有最低数量限制.4.这里不少题目在BUPT ACM FTP上面都有代码,请大家合理利用资源.5.50个题目要求每个题目都要写总结,养成良好的习惯.6.这个列表的目的在于让大家对各个方面的算法有个了解,也许要求有些苛刻,教条,请大家谅