hdu-5738 Eureka(组合计数+极角排序)

题目链接:

Eureka

Time Limit: 8000/4000 MS (Java/Others)  

  Memory Limit: 65536/65536 K (Java/Others)

Problem Description

Professor Zhang draws n points on the plane, which are conveniently labeled by 1,2,...,n. The i-th point is at (xi,yi). Professor Zhang wants to know the number of best sets. As the value could be very large, print it modulo 109+7.

A set P (P contains the label of the points) is called best set if and only if there are at least one best pair in P. Two numbers u and v (u,v∈P,u≠v) are called best pair, if for every w∈P, f(u,v)≥g(u,v,w), where f(u,v)=(xu−xv)2+(yu−yv)2−−−−−−−−−−−−−−−−−−−√ and g(u,v,w)=f(u,v)+f(v,w)+f(w,u)2.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1≤n≤1000) -- then number of points.

Each of the following n lines contains two integers xi and yi (−109≤xi,yi≤109) -- coordinates of the i-th point.

Output

For each test case, output an integer denoting the answer.

Sample Input

3

3

1 1

1 1

1 1

3

0 0

0 1

1 0

1

0 0

Sample Output

4

3

0

题意:

给 n个点,大于等于2个在同一条直线上的点可以构成一个集合,问你现在有多少个集合;

思路:

先把给的这些点按坐标排序,然后按顺序选一个点i,这个点i作为一定选到集合里面的点,然后再选枚举这个点之后的点j,形成一条直线,再看这条直线上没有被访问过的点k(i<k<n&&k!=j)有多少;假设有num个,那么就可以形成包含点i的集合2^num-1,同时这些点里面有重合的点,还有就是为降低复杂度,要用极角排序,但是最后判断的时候极角排序的精度好像又不太够,所有我就直接用原来的坐标判断的;

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>

using namespace std;

#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));

typedef  long long LL;

template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar());
    for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + ‘0‘);
    putchar(‘\n‘);
}

const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=1e5+10;
const int maxn=500+10;
const double eps=1e-9;

int n,vis[1010];
LL fx,fy,f[1010];
struct node
{
    double ang;
    LL x,y;
}po[1010],temp[1010];
int cmp1(node a,node b)
{
    return a.ang<b.ang;
}
int cmp(node a,node b)
{
    if(a.y==b.y)return a.x<b.x;
    return a.y<b.y;
}

int main()
{
        int t;
        read(t);
        f[0]=1;
        For(i,1,1008)
        {
            f[i]=f[i-1]*2%mod;
        }
        while(t--)
        {
            read(n);
            For(i,1,n)
            {
                read(po[i].x);read(po[i].y);
            }
            sort(po+1,po+n+1,cmp);
            LL ans=0;
            For(i,1,n-1)
            {
                int cnt=0,s=0;
                For(j,i+1,n)
                {
                    if(po[j].x==po[i].x&&po[j].y==po[i].y){s++;continue;}
                    temp[++cnt].ang=atan2(po[j].y-po[i].y,po[j].x-po[i].x);
                    temp[cnt].x=po[j].x;
                    temp[cnt].y=po[j].y;
                }
                sort(temp+1,temp+cnt+1,cmp1);
                fx=po[i].x,fy=po[i].y;
				int d=0;
                for(int j=1;j<=cnt;)
                {
                    int k,num=s+1;
                    for(k=j+1;k<=cnt;k++)
                    {
                        if((temp[k].y-fy)*(temp[j].x-fx)!=(temp[j].y-fy)*(temp[k].x-fx))break;
                        num++;
                    }
                    j=k;
                    ans=(ans+f[num]-1+mod)%mod;
                    d++;
                }
                ans=(ans-(LL)(d-1)*(f[s]-1+mod)%mod+mod)%mod;
            }
            cout<<ans<<endl;
        }
        return 0;
}

  

时间: 2024-08-06 07:54:36

hdu-5738 Eureka(组合计数+极角排序)的相关文章

LA 4064 (计数 极角排序) Magnetic Train Tracks

这个题和UVa11529很相似. 枚举一个中心点,然后按极角排序,统计以这个点为钝角的三角形的个数,然后用C(n, 3)减去就是答案. 另外遇到直角三角形的情况很是蛋疼,可以用一个eps,不嫌麻烦的话就用整数的向量做点积. 1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 6 typedef long long LL; 7 const int ma

HDU 3532 Max Angle(计算几何——极角排序)

传送门 Max Angle Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 704    Accepted Submission(s): 253 Problem Description Given many points in a plane, two players are playing an interesting game. Pl

HDU 5738 Eureka

传送门 题目大意: $给出平面上的n个点,每个点有唯一的标号(\text{label}),这n个标号的集合记作S,点可能重合.求满足下列条件的S的子集T的数目:$ $1. |T|\ge 2$ $2.T中的点共线$ Solution: $我们考虑其中至少有两个不同(指坐标不同,下同)点(符合条件)的子集T的数目,只包含一个点的子集T的数目很容易计算.$ $考虑两不同点u, v所决定的直线上的点,将这些点的集合记作P_{uv},考虑P_{uv}的子集对答案的贡献\text{cnt}_{u,v}.$

【极角排序+双指针线性扫】2017多校训练七 HDU 6127 Hard challenge

acm.hdu.edu.cn/showproblem.php?pid=6127 [题意] 给定平面直角坐标系中的n个点,这n个点每个点都有一个点权 这n个点两两可以连乘一条线段,定义每条线段的权值为线段两端点点权的乘积 现在要过原点作一条直线,要求这条直线不经过任意一个给定的点 在所有n个点两两连成的线段中,计算与这条直线有交点的线段的权值和 最大化这个权值和并输出 题目保证,给定的n个点不重合且任意两个点的连线不经过原点 [思路] 一条经过原点的直线把n个点分成两个半平面A,B 假设A中的点权

HDU 4832 组合计数dp

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 509    Accepted Submission(s): 198 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字

HDU Always Cook Mushroom (极角排序+树状数组)

Problem Description Matt has a company, Always Cook Mushroom (ACM), which produces high-quality mushrooms. ACM has a large field to grow their mushrooms. The field can be considered as a 1000 * 1000 grid where mushrooms are grown in grid points numbe

[HDU 3461] Saving Beans &amp; 组合计数Lucas定理模板

Saving Beans Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description Although winter is far away, squirrels have to work day and night to save beans. They need plenty of food to get through those long cold

poj2280Amphiphilic Carbon Molecules(极角排序)

链接 卡了几天的破题,对于hdu的那份数据,这就一神题.. 借助极角排序,枚举以每一个点进行极角排序,然后构造两条扫描线,一个上面一个下面,两条同时走,把上线和下线的点以及上线左边的点分别统计出来,如下图 样例3: 假如现在以d为p[0],那么所有可能结果一定是他与其他点的连线所分割的平面,那么首先以de为上线,下线的角度为上线+pi,两条线始终维护着这样的关系.de的下一个点为f,di的下一个点为c ,比较一下两者需要转的角度,选取较小角度转,注意一下相同的时候的处理. 1 #include

Hdu5032 极角排序+树状数组

题目链接 思路:参考了题解.对询问进行极角排序,然后用树状数组维护一下前缀和即可. /* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; const int maxn=1010; const int maxm=10