hdu5738-Eureka (重点 + 极角排序)

来源:互联网 发布:易语言源码网 编辑:程序博客网 时间:2024/05/16 04:09
<a target=_blank href="http://acm.hdu.edu.cn/showproblem.php?pid=5738" style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">题目链接:hdu5738</a>


题意:給n个点,选择一个点集合(最少两点),都在同一直线上,求有多少集合

首先, 把所有点按照(x,y)(x,y)双关键字排序, 然后枚举最左边的点ii, 那么其他点jj一定满足j > ij>i. 把在这个点右边的点都做下极角排序(按照\frac{1}{gcd(dx, dy)}(dx, dy)gcd(dx,dy)1(dx,dy)排序), 统计下共线的就好了. 需要注意下对重点的处理.

代码:

#include <map>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <cassert>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 1000010#define MOD 1000000007#define zero(x) (((x)>0?(x):-(x))<eps)#define LL long longint T;int n,m;LL f[12000];const LL mod=1e9+7;struct Node{    LL x,y;    double ang=0;} node[12000],temp[12000];bool cmp(Node a,Node b){    if(a.y==b.y)        return a.x<b.x;    return a.y<b.y;}bool cmp2(Node a,Node b){    if(fabs(a.ang-b.ang)>1e-9)        return a.ang<b.ang;    if(a.y==b.y)        return a.x<b.x;    return a.y<b.y;}int main(){    f[0]=1;    for(int i=1;i<10000;i++)        f[i]=(f[i-1]*2)%mod;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=0;i<n;i++)        {            scanf("%I64d%I64d",&node[i].x,&node[i].y);        }        sort(node,node+n,cmp);        LL ans=0;        for(int i=0;i<n-1;i++)        {            int cnt=0,s=0;            for(int j=i+1;j<n;j++)            {                if(node[j].x==node[i].x && node[j].y==node[i].y) {s++;continue;}                temp[cnt].ang=atan2 ((node[j].y-node[i].y),(node[j].x-node[i].x));                temp[cnt].x=node[j].x;                temp[cnt++].y=node[j].y;            }            sort(temp,temp+cnt,cmp2);            LL dif=0;            for(int j=0;j<cnt;j++)            {                int k,num=s+1;                for(k=j+1;k<cnt;k++)                {                    if((temp[k].y - node[i].y) * (temp[j].x-node[i].x) != (temp[j].y-node[i].y) * (temp[k].x-node[i].x)) break;                    num++;                }                dif++;                ans=(ans+f[num]-1+mod)%mod;                j=k-1;            }            ans=(ans-((dif-1) * (f[s]-1 + mod)%mod)+mod)%mod;        }        printf("%I64d\n",(ans+mod)%mod);    }    return 0;}


0 0
原创粉丝点击