Accept: 44 Submit: 235
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
黑暗之王有一片棋盘般的疆土,这片疆土有2*10^9行,有2*10^9列。假设这块疆土的行从上到下编号1到2*10^9,它的列从左到右也编号1到2*10^9。我们可以把第i行第j列的方格记为坐标(i,j)。
但是这偌大棋盘只有被给的N个线状区域才是允许通行的。每个线状区域被三个参数描述,ri,ai,bi(ai<= bi)。ri代表给定线状区域的行编号,ai代表线状区域的起始列编号,bi代表末尾编号。
现在国王想要从一个给定坐标方格(x0,y0)通过最小移动步数到达终点坐标方格(x1,y1),而且只能通过上述给出的允许通行的线状区域。
国王移动一步只能发生在相邻的方格之间。此外,如果两个方格至少共享一个点我们便认为他们相邻。
Input
有多组数据(<=30),处理到文件尾(EOF)。
每组数据第一行包含四个整数,x0, y0, x1, y1(1 <= x0, y0, x1, y1 <= 2*10^9),分别代表国王的初始坐标和终点坐标。
第二行有一个整数N (1 <= N <= 10^5),代表有N条可通行的线状区域。
接下里会有N行,第i行包含三个整数,ri,ai, bi (1 <= ri, ai bi <= 2*10^9),含义看题面。
数据允许线状区域会有交叉或者嵌套。
数据保证国王的起点方格和终点方格都是可通行的,并且两个区域不相同。另外保证所有线状区域的的长度总和不超过10^5。
1 <= x0, y0, x1, y1, ri, ai, bi<= 2*10^9,1 <= N <= 10^5
Output
如果没有一条道路使得国王从起始区域到达终点区域,则输出 -1。
否则,则输出国王的从起始区域到达终点区域的最小步数。
Sample Input
3
5 3 8
6 7 11
5 2 5
1 1 2 10
2
1 1 3
2 6 10
Sample Output
Source
福州大学第十三届程序设计竞赛
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define X first
#define Y second
using namespace std;
int const MAX = 1e5 + 5;
int stx, sty, edx, edy, n, ecnt;
int head[MAX];
int st, ed;
int dx[8] = {1, 1, 1, -1, -1, -1, 0, 0};
int dy[8] = {0, 1, -1, 0, 1, -1, 1, -1};
bool vis[MAX];
pair <int, int> p[MAX], t;
struct EDGE
{
int to, nxt;
}e[MAX << 3];
struct POINT
{
int pos, step;
};
void Init()
{
ecnt = 0;
memset(head, -1, sizeof(head));
}
void Add(int u, int v)
{
e[ecnt].to = v;
e[ecnt].nxt = head[u];
head[u] = ecnt ++;
}
int BFS()
{
memset(vis, false, sizeof(vis));
queue <POINT> q;
POINT s;
s.pos = st;
s.step = 0;
q.push(s);
vis[st] = true;
while(!q.empty())
{
POINT cur = q.front(), t;
q.pop();
if(cur.pos == ed)
return cur.step;
for(int i = head[cur.pos]; i != -1; i = e[i].nxt)
{
t.pos = e[i].to;
t.step = cur.step + 1;
if(!vis[t.pos])
{
vis[t.pos] = true;
q.push(t);
}
}
}
return -1;
}
int main()
{
while(scanf("%d %d %d %d", &stx, &sty, &edx, &edy) != EOF)
{
Init();
int cnt = 1, x, y1, y2;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d %d %d", &x, &y1, &y2);
for(int j = y1; j <= y2; j++)
p[cnt ++] = make_pair(x, j);
}
sort(p + 1, p + cnt + 1);
cnt = unique(p + 1, p + cnt + 1) - p - 1;
for(int i = 1; i <= cnt; i++)
{
for(int j = 0; j < 8; j++)
{
t = make_pair(p[i].X + dx[j], p[i].Y + dy[j]);
int pos = lower_bound(p + 1, p + cnt + 1, t) - p;
if(p[pos].X == p[i].X + dx[j] && p[pos].Y == p[i].Y + dy[j])
Add(i, pos);
}
}
st = lower_bound(p + 1, p + cnt + 1, make_pair(stx, sty)) - p;
ed = lower_bound(p + 1, p + cnt + 1, make_pair(edx, edy)) - p;
printf("%d\n", BFS());
}
}