Minimum Sum 平面最近点对

原创 2011年10月18日 19:13:09

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



Java面向对象

-
  • 1970年01月01日 08:00

LeetCode || Minimum Path Sum

Minimum Path Sum  Total Accepted: 19916 Total Submissions: 63796My Submissions Question  Solution ...
  • jiadebin890724
  • jiadebin890724
  • 2014-10-19 11:40:15
  • 4446

leetcode 64. Minimum Path Sum-最小路径和|动态规划

原题链接:64. Minimum Path Sum 【思路】 采用动态规划。动态规划要求利用到上一次的结果,是一种特殊的迭代思想,动态规划的关键是要得到递推关系式。对于本题,从原点到达(i, j)的最...
  • happyaaaaaaaaaaa
  • happyaaaaaaaaaaa
  • 2016-05-31 20:11:51
  • 2021

[LeetCode]64.Minimum Path Sum

【题目】 Given a m x n grid filled with non-negative numbers, find a path from top left to bottom r...
  • SunnyYoona
  • SunnyYoona
  • 2015-02-04 15:55:25
  • 1786

leetcode 209 : Minimum Size Subarray Sum

leetcode : Minimum Size Subarray Sum
  • xudli
  • xudli
  • 2015-05-14 06:15:11
  • 8353

712. Minimum ASCII Delete Sum for Two Strings

Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal....
  • zjucor
  • zjucor
  • 2017-10-23 10:16:34
  • 433

leetcode 599. Minimum Index Sum of Two Lists

1.题目Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favo...
  • u010529144
  • u010529144
  • 2017-05-29 18:53:55
  • 1149

LeetCode 209 - Minimum Size Subarray Sum

一、问题描述 Description:Description: Given an array of n positive integers and a positive integer ...
  • lisong694767315
  • lisong694767315
  • 2015-05-12 12:50:20
  • 6274

712. Minimum ASCII Delete Sum for Two Strings(动态规划)

最长子序列问题。
  • w_bu_neng_ku
  • w_bu_neng_ku
  • 2017-11-01 20:56:38
  • 418

HDU 3473 Minimum Sum

Minimum Sum Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T...
  • hqu_fritz
  • hqu_fritz
  • 2014-07-05 14:45:54
  • 614
收藏助手
不良信息举报
您举报文章:Minimum Sum 平面最近点对
举报原因:
原因补充:

(最多只允许输入30个字)