1320. 拯救奶牛

2019.3.2jzoj

1320. 拯救奶牛
贝希被困在一个三角形的迷宫之中。这个迷宫有N行(1 <= N <= 1000000)。比如下图是一个3行的迷宫。
  在这里插入图片描述
  迷宫的第i行有2*i-1个三角形,从左到右分别编号为(i,1)、(i,2)等等。贝希每次可以从一个三角形走到任意一个一个跟当前的三角形有邻边的三角形。比如说,如果她目前处于三角形(3,3),那么,她可以走到三角形(3,2)、(3,4)和(4,4)。贝希每次需要一分钟的时间来移动到下一个三角形。
  在这里插入图片描述
  农夫约翰发现贝希被困了!于是她跟踪贝希的iPhone手机(可怜的触摸屏~),得知贝希目前处于三角形(Si,Sj)。因为约翰对贝希有着无穷无尽的浓浓爱意,所以他希望贝希能尽可能快地回到他的身边。
  在迷宫的三角形之中,有M(1 <= M <= 10000)个是出口。在任何一个出口都可以让贝希逃离迷宫。一旦贝希进入一个作为出口的三角形,她用多一分钟就可以逃离这个迷宫。
  找到一个可以让贝希逃离迷宫最小时间T,并输出她应该从哪一个出口逃离迷宫,这个出口记为(OUTi,OUTj)。如果有多个出口同时需要时间T,输出那个行的编号小的出口,如果仍然有多个出口,输出那个列的编号小的。
Input
  第一行:两个由空格隔开的整数:N和M。
  第二行:两个由空格隔开的整数:Si和Sj。
  第三到第M+2行:第i+2行有两个由空格隔开的整数Ei和Ej,表示三角形(Ei,Ej)是出口。

Output
  第一行:两个由空格隔开的整数:OUTi和OUTj。
  第二行:一个单独的整数:T。
 
Sample Input
4 2
2 1
3 5
4 4 
Sample Output
4 4
4

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int n,m,s,t;
bool  k=0;//模拟 
struct node{
	int w,x,y;
}a[maxn];
inline int read(){
    int x=0,w=0;char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return w?-x:x;
}
bool cmp(node a,node b){
	if(a.w==b.w) {
		if(a.x==b.x) return a.y<b.y;
		else return a.x<b.x;
	}
	else return a.w<b.w;
}
void pd(int x,int y,int id){
	int t1=0,t2=0,t3=0,t4=0;
	int d=(x-s)<<1;
	if(k){
		if(x>s){
			t1=t+d-1;
			t2=t+d;//r
			t3=t;t4=t+1;//l
			if(y==t1) a[id].w=d;
			else if(y==t2) a[id].w=d+1;
			else if(y==t3) a[id].w=1+d;
			else if(y==t4) a[id].w=d;
			else{
				if(y>t2) a[id].w=y-t2+d+1;
				else if(y<t3) a[id].w=t3-y+1+d;
				else{
					if(y%2) a[id].w=d+1;
					else a[id].w=d; 
				}
			}
			return;
		}
		else if(x==s){
			a[id].w=abs(y-t)+1;
			return;		
		}
		else{
			d=(s-x)<<1;
			t1=t-d-1;
			t2=t-d;//r
			t3=t;t4=t+1;//l
			if(y==t1) a[id].w=d+2;
			else if(y==t2) a[id].w=d+1;
			else if(y==t3) a[id].w=1+d;
			else if(y==t4) a[id].w=d+2;// 
			else{
				if(y<t1) a[id].w=d+t1-y+2;
				else if(y>t4) a[id].w=y-t4+2+d;
				else{
					if(y%2) a[id].w=d+1;
					else a[id].w=d+2; 
				}
			}
			return;
		}
	}
	else{
		if(x>s){
			t1=t+d+1;
			t2=t+d;//r
			t3=t;t4=t-1;//l
			if(y==t1) a[id].w=d+2;
			else if(y==t2) a[id].w=d+1;
			else if(y==t3) a[id].w=1+d;
			else if(y==t4) a[id].w=d+2;
			else{
				if(y>t1) a[id].w=y-t1+d+2;
				else if(y<t4) a[id].w=t4-y+2+d;
				else{
					if(y%2) a[id].w=2+d;
					else a[id].w=1+d; 
				}
			}
			return;
		}
		else if(x==s){
			a[id].w=abs(y-t)+1;
			return;		
		}
		else{
			d=(s-x)<<1;
			t1=t-d;
			t2=t-d+1;//r
			t3=t;t4=t-1;//l
			if(y==t1) a[id].w=d+1;
			else if(y==t2) a[id].w=d;
			else if(y==t3) a[id].w=1+d;
			else if(y==t4) a[id].w=d;// 
			else{
				if(y<t1) a[id].w=t1-y+d+1;
				else if(y>t3) a[id].w=y-t3+1+d;
				else{
					if(y%2) a[id].w=d;
					else a[id].w=d+1; 
				}
			}
			return;
		}
	}
}
int main(){
	n=read(),m=read();
	s=read(),t=read();
	int x,y;
	if(t%2) k=1;//奇数 
	for(int i=1;i<=m;i++){
		a[i].x=read(),a[i].y=read();
		pd(a[i].x,a[i].y,i);		
	}
	sort(a+1,a+m+1,cmp);
	printf("%d %d\n",a[1].x,a[1].y);
	printf("%d",a[1].w);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值