C. King‘s Path

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;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108367997