1
12
2016
0

codeforces gym 100792g Garden Gathering

http://codeforces.com/gym/100792/problem/G

既然刚才写了平面几何技巧,干脆来个二连发。

看n=20w和这个题意感觉应该是经典问题,看了半个小时一点想法都没有_(:зゝ∠)_然后被阳神训斥了_(:зゝ∠)_然后一下子就懂了_(:зゝ∠)_

题意:定义两点距离为(\(\sqrt{2}-1)\)*max(abs(x[i]-x[j]),abs(y[i]-y[j]))+min(abs(x[i]-x[j]),abs(y[i]-y[j]))

然后求平面最远点对。

平面最远点对不是个经典nlog问题吗,看了一下这个和欧几里得距离不一样不会来_(:зゝ∠)_然后想了一下旋转45,发现并没有什么卵用,因为这个东西本来就是有45的路径的然后我整个人就懵逼了_(:зゝ∠)_

然后阳神就过来训斥了我_(:зゝ∠)_你这个东西不是O(n*8)的SB东西吗_(:зゝ∠)_

因为两点之间的距离中一共有3个不同的max或者min(abs也算作max(k,-k)),也就是说一共也就8种情况,因为两点之间的距离一定是8种情况里最大的一种,然后我们8种情况分别记录当前的最优点就行了。

怕没听懂还是写一下8种情况吧:

1、dis=(\(\sqrt{2}-1)\))*(x[i]-x[j])+y[i]-y[j];

2、dis=(\(\sqrt{2}-1)\))*(x[i]-x[j])+y[j]-y[i];

3、dis=(\(\sqrt{2}-1)\))*(x[j]-x[i])+y[i]-y[j];

4、dis=(\(\sqrt{2}-1)\))*(x[j]-x[i])+y[j]-y[i];

5、dis=(\(\sqrt{2}-1)\))*(y[i]-y[j])+x[i]-x[j];

6、dis=(\(\sqrt{2}-1)\))*(y[i]-y[j])+x[j]-x[i];

7、dis=(\(\sqrt{2}-1)\))*(y[j]-y[i])+x[i]-x[j];

8、dis=(\(\sqrt{2}-1)\))*(y[j]-y[i])+x[j]-x[i];

这样就很清晰了_(:зゝ∠)_单独对于每一种情况,在x[i]、y[i]相同的情况下,某个work(x[j],y[j])一定与dis有单调性,我们只要按照这个单调性维护最优点就行了_(:зゝ∠)_总复杂度空间O(1),时间O(n)

 

#include<cstdio>
#include<cmath>
using namespace std;
double t=sqrt(2)-1;
struct point{
    int x,y,k;
}p[200005],P[8];
int n,X,Y;
double ans;
double a[8]={t,1,t,1,-t,-1,-t,-1};
double b[8]={1,t,-1,-t,1,t,-1,-t};
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y),p[i].k=i;
    for(int i=0;i<8;i++)P[i]=p[1];
    ans=-1;
    for(int i=2;i<=n;i++){
        for(int j=0;j<8;j++){
            double s=(P[j].y-p[i].y)*b[j]+(P[j].x-p[i].x)*a[j];
            if(s>ans){
                X=P[j].k;
                Y=p[i].k;
                ans=s;
            }
        }
        for(int j=0;j<8;j++)if(p[i].x*a[j]+p[i].y*b[j]>P[j].x*a[j]+P[j].y*b[j])P[j]=p[i];
    }
    printf("%d %d\n",X,Y);
}

一边读一边做可以做到空间O(1)不想改了_(:зゝ∠)_

Category: codeforces | Tags: 平面几何 | Read Count: 1090

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com