timus 1207. Median on the Plane URAL 解題報告 計算幾何 求兩點把點均分

timus   1207. Median on the Plane  URAL   解題報告    計算幾何 求兩點把點均分

題目大意:給n個點,求出兩個點,使得他們所在的直線把點分成相同數量的兩部分,並且沒有三個點在同一條直線上!
思路:選定一個極點,用極座標排序法排序,然後選擇第一個和第n/2+1個點即可,就是座標爲0和n/2的點; 注意極座標排序的時候選定一個點作爲極點,該點必須是左下角那個點,當然你選右上角也沒事,必須使得這個點看其他點是180°的視角,否則無法排序;
注意坑在哪裏:  座標需要用double處理,不知道是題目給錯了,還是計算幾何中這裏需要保持精度採用double處理!
排序的時候要注意,極點選定之後使其和第一個點交換,並且不能再對其進行排序了


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include<map>
#include <vector>
const int N=10010;
const double EPS=1e-6;
using namespace std;
struct Node
{
    double x,y;
    int id;
}nod[N],tnod;

bool cmp(Node n1,Node n2)
{
    double x1=n1.x-nod[0].x,y1=n1.y-nod[0].y;
    double x2=n2.x-nod[0].x,y2=n2.y-nod[0].y;
    if(x1*y2-x2*y1+EPS<0)return true;
    return false;
}
int n;
int main()
{
    tnod.x=1000000001;tnod.y=1000000001;
    //cout<<tnod.x<<endl;
    cin>>n;int ind=0;
    for(int i=0;i<n;++i)
    {
       cin>>nod[i].x>>nod[i].y;
        nod[i].id=i+1;
        if(tnod.x>nod[i].x)
        {
           tnod=nod[i];ind=i;
        }else if(tnod.x==nod[i].x&&nod[i].y<tnod.y)
        {
            tnod=nod[i];ind=i;
        }
    } if(n==2){cout<<"1 2"<<endl;return 0;}

    swap(nod[0],nod[ind]);///選定極點之後使得極點爲第一個點,不要在對極點進行排序了

    sort(nod+1,nod+n,cmp);
    int ans1=nod[0].id;
    int ans2=nod[n/2].id;
    cout<<min(ans1,ans2)<<" "<<max(ans1,ans2)<<endl;

	return 0;
}
timus   1207. Median on the Plane  URAL   解題報告    計算幾何 求兩點把點均分

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章