• uva 12426 Counting Triangles 计算几何


    题意:给一个凸多边形,求以凸多边形的顶点为顶点的三角形中,有多少个面积小于给定数值K?

    思路:旋转卡壳+二分答案

    时间复杂度:n^2logn

      1 #include<iostream>
    2 #include<cstdio>
    3 #include<cmath>
    4 #include<cstring>
    5 using namespace std;
    6 #define MAXN 1001
    7 struct point
    8 {
    9 long long x,y;
    10 point() {}
    11 point(long long x0,long long(y0)): x(x0),y(y0) {}
    12 };
    13 int n,T;
    14 long long max_area;
    15 point a[2*MAXN];
    16 int edge[MAXN][MAXN][2];
    17 point operator -(const point &A,const point &B)
    18 {
    19 return point(A.x-B.x,A.y-B.y);
    20 }
    21 long long cross(point A,point B)
    22 {
    23 return A.x*B.y-A.y*B.x;
    24 }
    25 void rotate()
    26 {
    27 int i,k;
    28 int j1,j2;
    29 for(k=1;k<n;k++)
    30 {
    31 j1=1; j2=k+1;
    32 for(i=1;i<=n;i++)
    33 {
    34 if(i+k>n) break;
    35 while(abs(cross(a[i]-a[j1+1],a[i+k]-a[j1+1]))>abs(cross(a[i]-a[j1],a[i+k]-a[j1])))
    36 j1=j1%n+1;
    37 edge[i][i+k][0]=j1;
    38 while(abs(cross(a[i]-a[j2+1],a[i+k]-a[j2+1]))>abs(cross(a[i]-a[j2],a[i+k]-a[j2])))
    39 j2=j2%n+1;
    40 edge[i][i+k][1]=j2;
    41 }
    42 }
    43 }
    44 int binary(int i,int k,int j)
    45 {
    46 long long s;
    47 int left=i,right;
    48 int ans=0;
    49 if(k<i) right=k+n;
    50 else right=k;
    51 while(left<right)
    52 {
    53 int mid=(left+right)/2;
    54 s=abs(cross(a[i]-a[mid],a[j]-a[mid]));
    55 if(max_area<s) right=mid;
    56 else left=mid;
    57 if(right-left==1) break;
    58 }
    59 ans=left-i;
    60
    61 left=k;
    62 if(j<k) right=j+n;
    63 else right=j;
    64 while(left<right)
    65 {
    66 int mid=(left+right)/2;
    67 s=abs(cross(a[i]-a[mid],a[j]-a[mid]));
    68 if(max_area<s) left=mid;
    69 else right=mid;
    70 if(right-left==1) break;
    71 }
    72 ans+=(j+n-right)%n;
    73 return ans;
    74 }
    75 int solve()
    76 {
    77 int i,j;
    78 long long ans=0;
    79 int k1,k2;
    80 long long s;
    81 for(i=1;i<n;i++)
    82 for(j=i+1;j<=n;j++)
    83 {
    84
    85 k1=edge[i][j][0]; k2=edge[i][j][1];
    86 s=abs(cross(a[i]-a[k1],a[j]-a[k1]));
    87 if(j>i+1)
    88 {
    89 if(max_area>=s) ans+=j-i-1;
    90 else
    91 ans+=binary(i,k1,j);
    92 }
    93 if(i+n>j+1)
    94 {
    95 s=abs(cross(a[i]-a[k2],a[j]-a[k2]));
    96 if(max_area>=s) ans+=i+n-j-1;
    97 else
    98 ans+=binary(j,k2,i);
    99 }
    100 }
    101 return ans/3;
    102 }
    103 int main()
    104 {
    105 scanf("%d",&T);
    106 int i,j;
    107 for(j=1;j<=T;j++)
    108 {
    109 scanf("%d%lld",&n,&max_area);
    110 max_area*=2;
    111 for(i=1;i<=n;i++)
    112 {
    113 scanf("%lld%lld",&a[i].x,&a[i].y);
    114 a[n+i]=a[i];
    115 }
    116 rotate();
    117 printf("%d\n",solve());
    118 }
    119 return 0;
    120 }



  • 相关阅读:
    前导问题word使用技巧解决Word 生成目录时前导符不一致的问题(即通常所谓的目录中省略号大小不一致)
    安装用户debian7安装oracle11g
    字节文件MP3格式音频文件结构解析
    Linux下硬盘分区的最佳方案
    802.1x客户端软件 2.4版破解支持多网卡
    z9jpz.dll、gq0aku0.exe、cms2cmw.sys病毒
    Ghost批处理文件的基本格式
    利用ASP远程注册DLL的方法
    dllhost.exe系统进程介绍
    Unicode 和多字节字符集 (MBCS)
  • 原文地址:https://www.cnblogs.com/myoi/p/2360506.html
Copyright © 2020-2023  润新知