POJ 2049 Finding Nemo 优先队列 STL
2014-07-27 20:56
218 查看
题目链接:http://poj.org/problem?id=2049
题目利用了《海底总动员》的情节,小丑鱼尼莫迷路了,他老爸去营救他便是题意。
题目给出了这样的地图,说是假设地图由墙和门组成,忽略墙的厚度,地图上有门,没有墙的地方是可以自由行动的问可以经过最少多少道门便可以营救到尼莫。
这个题给的数据是墙的交点为整数点,但鱼爸爸实在非墙的地方自由移动。
因此,这个题有两个难点:
1.如果建图保存地图
2.如何在地图上遍历
由于题目是给出一个点(x,y),来表示一段墙
我便用一对X,Y来表示地图的块空间
用一个二维结构体数组保存,而每个结构体就是这样的一个单元。
如何保存便解决了。
至于遍历,果断BFS,但是因为要保证走的门最少那么就有一个在遍历下一个方格的时候存在选择哪条路的问题
为了保证走过的门最少,因此选用优先队列,不是让先入队列的先出队,而是让走的门最少的先出队。
要用优先队列,第一次尝试用STL,在
第三个参数出现了问题,不知道怎么写。
百度到说需要自己重新写重载,但不明白怎么写,好像函数内,函数外重载都不好弄,STL应该也不会让我这样(因为理解错为给类priority_queue写运算符重载了)
看了他们的代码发现自己想错了, 应该是把自己定义的结构体看为类,为这个类写运算符重载
然后写到结构体里便好了。
后期调试的过程中总是问题不断,最大的问题便是我忽略了X,Y应该互换位置表示,毕竟题目给的坐标和二维数组的表示坐标是不一样的。
最后一组测试数据:
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
答案是2
而不是4
在讨论里看到的数据,就是这个让我发现了X,Y需要互换的大漏洞,然后就A了。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <cmath>
#define MAX 1000000
using namespace std;
struct node
{
int eg[4];
} MAP[300][300];
bool vis[300][300];
struct Tmp { int x,y; int t; bool operator<(const Tmp & b) const { return t > b.t; } };
int bfs (int x,int y,int fx,int fy)
{
Tmp tmp,now;
priority_queue<Tmp,vector <Tmp>,less<Tmp> > que;
memset(vis,0,sizeof(vis));
now.x = x;
now.y = y;
now.t = 0;
que.push (now);
while (!que.empty())
{
now = que.top();
que.pop();
//cout << now.t << endl;
if (now.x == fx && now.y == fy)
return now.t;
if (!vis[now.x][now.y])
{
//cout << now.x << ' ' << now.y << '-' << now.t<< endl;
vis[now.x][now.y] = 1;
for (int i = 0;i < 4;i++)
{
if (MAP[now.x][now.y].eg[i] != 1)
{
tmp = now;
if (i == 0)
{
tmp.x--;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}else if (i == 1)
{
tmp.y++;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}else if (i == 2)
{
tmp.x++;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}else if (i == 3)
{
tmp.y--;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}
if (tmp.x>=0 && tmp.y >= 0 && tmp.x < 300 && tmp.y < 300 && !vis[tmp.x][tmp.y])
que.push(tmp);
}
}
}
}
return -1;
}
int main (void)
{
int m,k;
while (scanf ("%d%d",&m,&k),m != -1 || k != -1)
{
memset(MAP,0,sizeof (MAP));
int x,y,d,t,i;
for (i = 0;i < m;i++)
{
scanf ("%d%d%d%d",&x,&y,&d,&t);
int j;
if (d) //y
{
for (j = 0;j < t;j++)
{
MAP[299 - y - j][x].eg[3] = 1;
MAP[299 - y - j][x - 1].eg[1] = 1;
}
}else //x
{
for (j = 0;j < t;j++)
{
MAP[299 - y][x + j].eg[2] = 1;
MAP[299 - y + 1][x + j].eg[0] = 1;
}
}
}
for (i = 0;i < k;i++)
{
scanf ("%d%d%d",&x,&y,&d);
int j;
if (d) //y
{
MAP[299 - y][x].eg[3] = 2;
MAP[299 - y][x - 1].eg[1] = 2;
}else //x
{
MAP[299 - y][x].eg[2] = 2;
MAP[299 - y + 1][x].eg[0] = 2;
}
}
double fx,fy;
scanf ("%lf%lf",&fx,&fy);
int ifx = int (fx);
int ify = int (fy);
if (k == 0 && m == 0)
printf ("0\n");
else if (fx < 0 || fx > 199 || fy < 0 || fy > 199)
printf("0\n");
else
{
int ans = bfs (299,0,299 - ify,ifx);
printf ("%d\n",ans);
}
}
return 0;
}
题目利用了《海底总动员》的情节,小丑鱼尼莫迷路了,他老爸去营救他便是题意。
题目给出了这样的地图,说是假设地图由墙和门组成,忽略墙的厚度,地图上有门,没有墙的地方是可以自由行动的问可以经过最少多少道门便可以营救到尼莫。
这个题给的数据是墙的交点为整数点,但鱼爸爸实在非墙的地方自由移动。
因此,这个题有两个难点:
1.如果建图保存地图
2.如何在地图上遍历
由于题目是给出一个点(x,y),来表示一段墙
我便用一对X,Y来表示地图的块空间
用一个二维结构体数组保存,而每个结构体就是这样的一个单元。
如何保存便解决了。
至于遍历,果断BFS,但是因为要保证走的门最少那么就有一个在遍历下一个方格的时候存在选择哪条路的问题
为了保证走过的门最少,因此选用优先队列,不是让先入队列的先出队,而是让走的门最少的先出队。
要用优先队列,第一次尝试用STL,在
priority_queue<Tmp,vector <Tmp>,less<Tmp> > que;
第三个参数出现了问题,不知道怎么写。
百度到说需要自己重新写重载,但不明白怎么写,好像函数内,函数外重载都不好弄,STL应该也不会让我这样(因为理解错为给类priority_queue写运算符重载了)
看了他们的代码发现自己想错了, 应该是把自己定义的结构体看为类,为这个类写运算符重载
然后写到结构体里便好了。
struct Tmp { int x,y; int t; bool operator<(const Tmp & b) const { return t > b.t; } };
后期调试的过程中总是问题不断,最大的问题便是我忽略了X,Y应该互换位置表示,毕竟题目给的坐标和二维数组的表示坐标是不一样的。
最后一组测试数据:
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
答案是2
而不是4
在讨论里看到的数据,就是这个让我发现了X,Y需要互换的大漏洞,然后就A了。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <cmath>
#define MAX 1000000
using namespace std;
struct node
{
int eg[4];
} MAP[300][300];
bool vis[300][300];
struct Tmp { int x,y; int t; bool operator<(const Tmp & b) const { return t > b.t; } };
int bfs (int x,int y,int fx,int fy)
{
Tmp tmp,now;
priority_queue<Tmp,vector <Tmp>,less<Tmp> > que;
memset(vis,0,sizeof(vis));
now.x = x;
now.y = y;
now.t = 0;
que.push (now);
while (!que.empty())
{
now = que.top();
que.pop();
//cout << now.t << endl;
if (now.x == fx && now.y == fy)
return now.t;
if (!vis[now.x][now.y])
{
//cout << now.x << ' ' << now.y << '-' << now.t<< endl;
vis[now.x][now.y] = 1;
for (int i = 0;i < 4;i++)
{
if (MAP[now.x][now.y].eg[i] != 1)
{
tmp = now;
if (i == 0)
{
tmp.x--;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}else if (i == 1)
{
tmp.y++;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}else if (i == 2)
{
tmp.x++;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}else if (i == 3)
{
tmp.y--;
if (MAP[now.x][now.y].eg[i] == 2)
tmp.t++;
}
if (tmp.x>=0 && tmp.y >= 0 && tmp.x < 300 && tmp.y < 300 && !vis[tmp.x][tmp.y])
que.push(tmp);
}
}
}
}
return -1;
}
int main (void)
{
int m,k;
while (scanf ("%d%d",&m,&k),m != -1 || k != -1)
{
memset(MAP,0,sizeof (MAP));
int x,y,d,t,i;
for (i = 0;i < m;i++)
{
scanf ("%d%d%d%d",&x,&y,&d,&t);
int j;
if (d) //y
{
for (j = 0;j < t;j++)
{
MAP[299 - y - j][x].eg[3] = 1;
MAP[299 - y - j][x - 1].eg[1] = 1;
}
}else //x
{
for (j = 0;j < t;j++)
{
MAP[299 - y][x + j].eg[2] = 1;
MAP[299 - y + 1][x + j].eg[0] = 1;
}
}
}
for (i = 0;i < k;i++)
{
scanf ("%d%d%d",&x,&y,&d);
int j;
if (d) //y
{
MAP[299 - y][x].eg[3] = 2;
MAP[299 - y][x - 1].eg[1] = 2;
}else //x
{
MAP[299 - y][x].eg[2] = 2;
MAP[299 - y + 1][x].eg[0] = 2;
}
}
double fx,fy;
scanf ("%lf%lf",&fx,&fy);
int ifx = int (fx);
int ify = int (fy);
if (k == 0 && m == 0)
printf ("0\n");
else if (fx < 0 || fx > 199 || fy < 0 || fy > 199)
printf("0\n");
else
{
int ans = bfs (299,0,299 - ify,ifx);
printf ("%d\n",ans);
}
}
return 0;
}
相关文章推荐
- POJ 2049 Finding Nemo BFS 三维数组存状态, 优先队列优化时间与空间
- poj 3253 Fence Repair (STL优先队列)
- POJ 3253 Fence Repair(STL之优先队列)
- POJ 2442 Sequence (STL优先队列)
- POJ 3481 Double Queue(STL之双向优先队列)
- 【POJ】 2442——Sequence【STL—优先队列】
- POJ -3253 优先队列 STL
- POJ 3253 STL优先队列
- POJ 3253 STL优先队列
- POJ 2049 Finding Nemo(SPFA)
- STL 优先队列 定义 优先级
- c++STL中优先队列的使用
- POJ 3253 优先队列 Fence Repair
- POJ ROADS DFS BFS 优先队列 入门
- POJ 3253 Fence Repair(优先队列构造哈夫曼树)
- 【优先队列】【堆】STL之priority_queue、make_heap()、push_heap()、pop_heap()、容器适配器
- poj-2442-Sequence-优先队列||堆
- C++ STL优先队列(STL堆)
- POJ2010-Moo University - Financial Aid-优先队列
- hdoj 1509 Windows Message Queue 【STL 优先队列】