题解 P5086 【坐标】

· · 题解

本题居然变成了比赛里最送分的题目,还成了提高+/省选-,这恶意评分怕是有毒。

题意解析:

找两个优美坐标,要想知道所有优美坐标的j-i的最小值和i+j的最大值,

$Ai$=$Yi$-$Xi$;$Bi$=$Zi$-$Yi$;$Ci$=$Qi$-$Zi$; 所以只要满足 $Ai$=$Aj$ $Bi$=$Bj$ $Ci$=$Cj$ 即可满足要求 在加一个数组表示输入时他的位置,我们将四个数组四关键字从小到大排序一下,再记录一下最值即可,用最长不降子序列,时间复杂度$O$($N$),算上快排$O$($N$ $log$ $N$) 代码(标程是$Pascal$,但$C++$快排要简单,且怕与vecont程序重复,放$C++$): ```cpp #include<bits/stdc++.h> using namespace std; struct node { long long x,y,z,k; }a[1000010]; int a1,b1,c1,d1,n,i,mi,ma; template <typename T> void read(T &x) { x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()); for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; } int cmp(node a,node b) { if (a.x<b.x) return 1;if (a.x>b.x) return 0; if (a.y<b.y) return 1;if (a.y>b.y) return 0; if (a.z<b.z) return 1;if (a.z>b.z) return 0; if (a.k<b.k) return 1;if (a.k>b.k) return 0; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d %d %d %d",&a1,&b1,&c1,&d1); a[i].x=b1-a1;a[i].y=c1-b1;a[i].z=d1-c1;a[i].k=i; } sort(a+1,a+1+n,cmp); mi=INT_MAX;ma=-INT_MAX; for (int i=2;i<=n;i++) if (a[i].x==a[i-1].x&&a[i].y==a[i-1].y&&a[i].z==a[i-1].z) { if (a[i].k-a[i-1].k<mi) mi=a[i].k-a[i-1].k; if (a[i].k+a[i-1].k>ma) ma=a[i].k+a[i-1].k; } printf("%lld %lld\n",mi,ma); return 0; } ```