https://codeforces.com/problemset/problem/242/C
题面:
有一个国王站在一个 10^9109\times×10^9109 的国际象棋棋盘上。
规定第 ii 行第 jj 列的位置表示为( ii ,jj )。
在给定的国际象棋棋盘上有一些格子是允许通过的。
国际象棋棋盘的所有允许通过的格子都以n个部分的形式给出。
每段用三个整数 r_iri a_iai b_ibi 表示( a_i \le b_iai≤bi )。
意思是在 r_iri 行中第 a_iai 个格子到第 b_ibi 个格子是允许通过的。
国王可以移动到与它相邻的任意一个格子里(只能走一步)。
如果两个格子有至少一个公用的点,那么就认为他们是相邻的。
求出国王从( x_0x0 , y_0y0 )移动至( x_1x1 , y_1y1 )的最少步数。
输入格式:
第一行包含四个由空格分隔的整数 x_0x0,y_0y0,x_1x1,y_1y1 ,表示国王的初始和最终位置。
第二行包含一个整数 nn ,表示有 nn 段可以通过的格子。
接下来的 nn 行则是这 nn 个部分中可通行的格子的描述(包含三个由空格隔开的整数r_iri ,a_iai ,b_ibi)。
输出格式:
如果在初始位置和最终位置之间没有路径,输出 -1−1。
否则输出一个整数:国王从初始位置到最终位置所需的最小移动次数。
说明/提示:
提示:
保证国王的初始和最终位置是允许通过的格子。
保证国王的初始和最终位置不一致。
保证所有给定部分的总长度不超过 10^5105 。
数据范围:
11 \le≤ x_0x0 , y_0y0 , x_1x1 , y_1y1 \le≤ 10^9109
11 \le≤ nn \le≤ 10^5105
11 \le≤ r_iri ,a_iai ,b_ibi \le≤ 10^9109
a_i \le b_iai≤bi
样例说明:
样例1:
国王的初始位置在( 55, 77 ),目标位置则是( 66 , 1111 )。
其中有三个部分可以通过:
第五行的第三列到第八列,第六行的第七列到第十一列,第五行的第二列到第五列。
在这种情况下,最少需要 44 步才能到达目标位置。
如图,红框内是可以通过的格子,由 AA 到 II 再到 BB 即是一种最短的情况。
输入输出样例
输入 #1复制
5 7 6 11 3 5 3 8 6 7 11 5 2 5
输出 #1复制
4
输入 #2复制
3 4 3 10 3 3 1 4 4 5 9 3 10 10
输出 #2复制
6
输入 #3复制
1 1 2 10 2 1 1 3 2 6 10
输出 #3复制
-1
思路:比较明显的bfs,考虑到不能邻接矩阵存,用vector<>存一边也是可以的。由于题目有一句输入总长<=1e5,所以可以暴力。直接哈希一下暴力bfs。
(i,j)的点变到(i*1e9+j,0)去bfs就可以了。bfs的还是在原来的点上,不过不用存,省空间。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
int dx[8]={-1,-1,-1,0,0,1,1,1};
int dy[8]={-1,0,1,-1,1,-1,0,1};
map<LL,bool>map1;
struct node{
LL x,y,val,step;
};
LL getpos(LL x,LL y)
{
return 1e9*x+y;
}
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL x0,y0,x1,y1;cin>>x0>>y0>>x1>>y1;
LL n;cin>>n;
for(LL i=1;i<=n;i++){
LL _r,_a,_b;cin>>_r>>_a>>_b;
for(LL j=_a;j<=_b;j++){
map1[getpos(_r,j)]=1;
}
}
queue<node>q;
q.push({x0,y0,getpos(x0,y0),0});
map1[getpos(x0,y0)]=1;
while(q.size())
{
node u=q.front();q.pop();
if(u.x==x1&&u.y==y1)//判终点
{
cout<<u.step<<endl;return 0;
}
for(int i=0;i<8;i++){
LL v1=u.x+dx[i];LL v2=u.y+dy[i];LL v3=getpos(v1,v2);LL v4=u.step+1;
if(map1[v3]==1&&v1>=1&&v1<=1e9&&v2>=1&&v2<=1e9)
{
q.push({v1,v2,v3,v4});
map1[v3]=0;
}
}
}
cout<<"-1"<<endl;
return 0;
}