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