题解 P5086 【坐标】
Kevin_Wa
·
·
题解
本题居然变成了比赛里最送分的题目,还成了提高+/省选-,这恶意评分怕是有毒。
题意解析:
找两个优美坐标,要想知道所有优美坐标的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;
}
```