zoukankan      html  css  js  c++  java
  • 选点问题

                                                 选点问题

    Description

    陶陶和鹏鹏在玩一个十分有趣的游戏!已知平面上有n个不同的点(保证不存在任意3个点共线),陶陶首先任意选取其中2个不同的点a,b,并连线得到线段AB,之后鹏鹏从剩下的n-2个点中任意选取2个不同的点c,d,并同样连线得到线段CD。 对于陶陶选择的点a,b,鹏鹏可能有若干种选择c,d的方案,使得CD与AB相交!易知,陶陶有n(n—1)/2种方案选择a,b。对于陶陶的第i种选择,假设鹏鹏有Ki种方案选择c,d使得AB和CD相交。 ★编程任务: 请计算输出陶陶和鹏鹏游戏的估价值T,其定义为: 其中Fib(x)表示第x项斐波那契数,它满足:

    由于T能比较大,请输出T模上1000000007的结果。

    Input Format

    输入文件名为point.in。 第一行一个整数n,表示平面上有n(n<=200)个点。接下来n行,给出n个点的坐标(xi,yi)。 输入的坐标均为整数,取值范围是:-100,000到100,000。

    Output Format

    输出文件名为point.out。 输出一行一个整数,表示T模上1,000,000,007的结果。

    Sample Input

    4
    0 0
    0 1
    1 0
    1 1

    Sample Output

    4

    菲波那切数列可以暴力求,然后这个公式也没有什么能变形的地方,反正就是告诉你:求相交线段的数目。
    我们考虑每个点所作出的贡献。

    如图,对于每个O,我们枚举A点和B点,此时,我们只需要计算OA,OB的反向延长线范围内的点数num,然后tot[A][B]-=num即可!,至于为什么呢,因为我们计算这部分点和O相连的时候,无法和AB相交,然而我们却无法直接计算,因为OAB三角形内还有部分不合法的点对,因此我们利用容斥原理,每次只减去一个方向的点,最后得到的便是答案。

    
    
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<string>
     6 #include<algorithm>
     7 #define ll long long
     8 const ll MOD=1000000007;
     9 const double pi=acos(-1),eps=1e-13;
    10 int f[200005],tot[205][205];
    11 int n;
    12 struct Point{
    13     int x,y,id;
    14     double ang;
    15 }p[200005],t[200005];
    16 int sign(double x){
    17     return x<-eps?-1:x>eps;
    18 }
    19 ll powit(ll x,int y){
    20     ll ans=1;
    21     while (y){
    22         if (y&1) ans=(ans*x)%MOD;
    23         x=(x*x)%MOD;
    24         y/=2; 
    25     }
    26     return ans;
    27 }
    28 bool cmp(Point x,Point y){
    29     return x.ang<y.ang;
    30 }
    31 void Fib(){
    32     f[0]=1;
    33     f[1]=1;
    34     for (int i=2;i<=n*n;i++) f[i]=(f[i-1]+f[i-2])%(MOD-1);
    35 }
    36 void solve(){
    37     for (int i=1;i<=n;i++){
    38         int cnt=0;
    39         for (int j=1;j<=n;j++){
    40             if (j==i) continue;
    41             p[++cnt]=t[j];
    42             p[cnt].ang=std::atan2(t[j].y-t[i].y,t[j].x-t[i].x);
    43         }
    44         std::sort(p+1,p+n,cmp);
    45         for (int j=1;j<n;j++){
    46             p[n-1+n-1+j]=p[n-1+j]=p[j];
    47             p[n-1+j].ang=p[j].ang+2*pi;
    48             p[n-1+n-1+j].ang=p[n-1+j].ang+2*pi;
    49         }
    50         int l=1;
    51         for (int j=1;j<n;j++){
    52             int r=j+1;
    53             while (sign(p[l].ang-p[j].ang-pi)<0) ++l;
    54             for (int k=j+1;sign(p[k].ang-p[j].ang-pi)<=0;k++){
    55                  while (sign(p[r+1].ang-p[k].ang-pi)<=0) r++;
    56                  tot[p[k].id][p[j].id]=tot[p[j].id][p[k].id]+=k-j-1-(r-l+1); 
    57             }  
    58         }
    59     }
    60     ll     ans=1;
    61     for (int i=1;i<=n;i++)
    62      for (int j=i+1;j<=n;j++){
    63          tot[i][j]/=2;
    64          ans=(ans*(1+powit(tot[i][j],f[tot[i][j]])%MOD))%MOD;
    65      }
    66     printf("%lld",ans); 
    67 }
    68 int main(){
    69     scanf("%d",&n);
    70     for (int i=1;i<=n;i++){
    71         scanf("%d%d",&t[i].x,&t[i].y);
    72         t[i].id=i;
    73     }
    74     Fib();
    75     solve();
    76 }


  • 相关阅读:
    MySQL的备份
    Linux下MySQL安装及配置
    MySQL的优化
    MySQL的基本操作
    python文件操作练习之文件备份
    文件操作练习之统计目录大小
    SQLite
    PyMySQL模块
    python语法练习题之九九乘法表
    类装饰器
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5266874.html
Copyright © 2011-2022 走看看