背景 Background
LHX教主最近总困扰于前来膜拜他的人太多了,所以他给他的花园加上了一道屏障。
描述 Description
可以把教主的花园附近区域抽像成一个正方形网格组成的网络,每个网格都对应了一个坐标(均为整数,有可能为负),若两个网格(x1, y1),(x2, y2)有|x1 - x2| + |y1 - y2| = 1,则说这两个网格是相邻的,否则不是相邻的。教主在y = 0处整条直线上的网格设置了一道屏障,即所有坐标为(x, 0)的网格。当然,他还要解决他自己与内部人员的进出问题,这样教主设置了N个入口a1, a2, …, aN可供进出,即对于y = 0上的所有网格,只有 (a1, 0),(a2, 0), ……, (aN, 0) 可以通过,之外的所有纵坐标为0的网格均不能通过,而对于(x, y)有y不为0的网格可以认为是随意通过的。现在教主想知道,给定M个点对(x1, y1),(x2, y2),并且这些点均不在屏障上,询问从一个点走到另一个点最短距离是多少,每次只能从一个格子走到相邻的格子。
输入格式 Input Format
输入的第1行为一个正整数N,为屏障上入口的个数。第2行有N个整数,a1, a2, …, aN,之间用空格隔开,为这N个入口的横坐标。第3行为一个正整数M,表示了M个询问。接下来M行,每行4个整数x1, y1, x2, y2,有y1与y2不等于0,表示了一个询问从(x1, y1)到(x2, y2)的最短路。
输出格式 Output Format
输出共包含m行,第i行对于第i个询问输出从(x1, y1)到(x2, y2)的最短路距离是多少。
这是这次模拟赛最简单的一道题,(虽然当时我出了点小错误)
//分两种情况,一种坐标直接相减
//一种求出距离最近的一个入口就可以啦
#include<fstream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cstdio>
#define oo 1147483647
using namespace std;
int m,n;
int a[100010],tt,ans;
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int main()
{
freopen("orz.in","r",stdin);
freopen("orz.out","w",stdout);
int i;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[n+1]=1<<29;
a[0]=-oo;
qsort(a+1,n,sizeof(int),cmp);
scanf("%d",&m);
int x1,x2,y1,y2;
for (i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
ans=0;
if ((y1>0&&y2>0)||(y1<0&&y2<0))
{
ans=(int)abs((double)(y1-y2))+(int)abs((double)(x1-x2));
printf("%d\n",ans);
continue;
}
if (x1>x2) swap(x1,x2);
ans=oo;
int l=1,r=n,mid;
while (l<=r)
{
mid=(l+r)>>1;
if (a[mid]>=x1 && a[mid-1]<x1)
{
if (ans>(a[mid]-x1+abs(a[mid]-x2))) ans=a[mid]-x1+abs(a[mid]-x2);
if (mid>1) if (ans>(x1-a[mid-1]+abs(a[mid-1]-x2))) ans=x1-a[mid-1]+abs(a[mid-1]-x2);
break;
}
if (a[mid]<x1) l=mid+1;
if (a[mid]>x1) r=mid-1;
}
l=1;r=n;mid;
while (l<=r)
{
mid=(l+r)>>1;
if (a[mid]<=x2 && a[mid+1]>x2)
{
if (ans>(x2-a[mid]+abs(x1-a[mid]))) ans=x2-a[mid]+abs(x1-a[mid]);
if ((mid+1)<=n)if (ans>(a[mid+1]-x2+abs(x1-a[mid+1]))) ans=a[mid+1]-x2+abs(x1-a[mid+1]);
break;
}
if (a[mid]<x2) l=mid+1;
if (a[mid]>x2) r=mid-1;
}
ans+=(int)abs((double)(y1-y2));
printf("%d\n",ans);
}
return 0;
}
浙公网安备 33010602011771号