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 解題報告 計算幾何 求兩點把點均分