poj 3512 Incidental Points 计算几何

来源:互联网 发布:音频裁剪软件 编辑:程序博客网 时间:2024/05/21 10:32

题意:

给n个点,判断其中最多有多少个点共线。

分析:

n<=1000,n^3的算法会TLE。将所有点按y从小到大排序,若y相同按x排序,这样每次确定跟点i最多有多少点共线就只需看要下标比i大的点了。对于每个点i,将下标比i大的点按与i成的角度排序,这样所有与i共线的点必然在新排序中相邻,遍历一遍取最大值就可以了。n^2*logn的复杂度。

代码:

//poj 3512//sepNINE#include<iostream>#include<algorithm>using namespace std;char tmp[1024];int n,cases,end;struct Point{__int64 x,y;}p[1024],np[1024];int cmp(Point a,Point b){if(a.y!=b.y)return a.y<b.y;return a.x<b.x;}int cmp1(Point a,Point b){if(a.x*b.y==a.y*b.x)return 1;return a.x*b.y>a.y*b.x;}void solve(){if(n==1){printf("%d. %d\n",++cases,1);return ;}int ans=2;int i,j,k;sort(p,p+n,cmp);for(i=0;i<n;++i){int num,cnt;num=1;cnt=0;for(j=i+1;j<n;++j){np[num].x=p[j].x-p[i].x;np[num].y=p[j].y-p[i].y;++num;}np[0].x=0,np[0].y=0;if(num<3)continue;sort(np+1,np+num,cmp1);for(j=1;j<num;++j)if(np[j].x*np[j-1].y==np[j].y*np[j-1].x)++cnt;else{ans=max(ans,cnt+1);cnt=1;}ans=max(ans,cnt+1);}printf("%d. %d\n",++cases,ans);}int main(){end=n=cases=0;while(1){gets(tmp); if(tmp[0]=='-'&&tmp[1]=='-'){if(n>0)solve();n=0;++end;if(end==2)break;}else{sscanf(tmp,"%I64d%I64d",&p[n].x,&p[n].y);end=0;++n;}}return 0;} 


0 0