# Minimum Sum 平面最近点对

You are given a set of n vectors on a plane. For each vector you are allowed to multiply any of its coordinates by -1. Thus, each vector vi = (xi, yi) can be transformed into one of the following four vectors:

• vi1 = (xi, yi),
• vi2 = ( - xi, yi),
• vi3 = (xi,  - yi),
• vi4 = ( - xi,  - yi).

You should find two vectors from the set and determine which of their coordinates should be multiplied by -1 so that the absolute value of the sum of the resulting vectors was minimally possible. More formally, you should choose two vectorsvivj (1 ≤ i, j ≤ n, i ≠ j) and two numbers k1k2 (1 ≤ k1, k2 ≤ 4), so that the value of the expression |vik1 + vjk2| were minimum.

Input

The first line contains a single integer n (2 ≤ n ≤ 105). Then n lines contain vectors as pairs of integers "xi yi" ( - 10000 ≤ xi, yi ≤ 10000), one pair per line.

Output

Print on the first line four space-separated numbers "i k1 j k2" — the answer to the problem. If there are several variants the absolute value of whose sums is minimum, you can print any of them.

Sample test(s)
input
5
-8 -3
-9 -6
-4 9
5 3
9 3

output
5 1 1 1

input
5
-3 -8
-9 10
-9 0
-9 -2
-6 5

output
4 4 3 3

Note

A sum of two vectors v = (xv, yv) and u = (xu, yu) is vector s = v + u = (xv + xu, yv + yu).

An absolute value of vector v = (x, y) is number .

In the second sample there are several valid answers, such as:

(3 1 4 2), (3 1 4 4), (3 4 4 1), (3 4 4 3), (4 1 3 2), (4 1 3 4), (4 2 3 1).

//

#include<iostream>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=200000;
const int inf=(1<<30);
struct Point
{
double x,y;//坐标
int k;
int id;//标号
};
int n;//点数
Point a[maxn];
int cx,cy;//最近点对
int k1,k2;
double cmin;
double dis(Point h,Point k)
{
return sqrt((h.x-k.x)*(h.x-k.x)+(h.y-k.y)*(h.y-k.y));
}
bool cmp(Point h,Point k)
{
if(h.x!=k.x) return h.x<k.x;
return h.y<k.y;
}
int y[maxn],len;
bool cmp2(int i,int j)
{
return a[i].y<a[j].y;
}
void solve(int l,int r)
{
if(l==r) return ;
if(l==r-1)
{
double tmp=dis(a[l],a[r]);
if(tmp<cmin) cmin=tmp,cx=a[l].id,k1=a[l].k,cy=a[r].id,k2=a[r].k;
}
if(l==r-2)
{
double l1=dis(a[l],a[l+1]);
double l2=dis(a[l+1],a[l+2]);
double l3=dis(a[l],a[l+2]);
if(l1<l2&&l1<l3)
{
if(l1<cmin) cmin=l1,cx=a[l].id,k1=a[l].k,cy=a[l+1].id,k2=a[l+1].k;
}
if(l2<l1&&l2<l3)
{
if(l2<cmin) cmin=l2,cx=a[l+1].id,k1=a[l+1].k,cy=a[l+2].id,k2=a[l+2].k;
}
if(l3<cmin) cmin=l3,cx=a[l].id,k1=a[l].k,cy=a[l+2].id,k2=a[l+2].k;
}
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
len=0;
for(int i=l;i<=r;i++)
{
if(fabs(a[i].x-a[mid].x)<cmin)
{
y[len++]=i;
}
}
sort(y,y+len,cmp2);
for(int i=0;i<len;i++)
{
for(int j=i+1,cnt=1;j<len&&cnt<=7;j++,cnt++)
{
double tmp=dis(a[y[i]],a[y[j]]);
if(tmp<cmin)
{
cmin=tmp,cx=a[y[i]].id,k1=a[y[i]].k,cy=a[y[j]].id,k2=a[y[j]].k;
}
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
while(scanf("%d",&n)==1)
{
cmin=inf;
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&a[i].x,&a[i].y);
if(a[i].x>=0&&a[i].y>=0) a[i].k=1;
else if(a[i].x<0&&a[i].y<0) a[i].k=4;
else if(a[i].x<0) a[i].k=2;
else a[i].k=3;
a[i].x=fabs(a[i].x);a[i].y=fabs(a[i].y);
a[i].id=i+1;
}
sort(a,a+n,cmp);
solve(0,n-1);
printf("%d %d %d %d\n",cx,k1,cy,5-k2);
//printf("%d %d/n",min(cx,cy),max(cx,cy));
//printf("%.3lf\n",cmin);
}
return 0;
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：Minimum Sum 平面最近点对 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)