zoukankan      html  css  js  c++  java
  • Convex(扫描线降维)

    Convex

    Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1838    Accepted Submission(s): 552


    Problem Description
    Your task is very simple. You will get the coordinates of n points in a plane. It is guaranteed that there are no three points on a straight line. You can choose any four points from these points to construct a quadrangle. Now, please tell me how many convex quadrangles you can construct.
     
    Input
    The first line of input contain an integer z (z ≤ 20), indicating the number of test cases.
    For each test case, the first line contain an integer n (4 ≤ n ≤ 700), indicating the number of points. Each of the next n lines contains two integers x and y (-1000000 ≤ x, y ≤ 1000000), indicating the coordinate of corresponding point.

     
    Output
    For each test case, just output a single integer, the number of convex quadrangles you can construct.
     
    Sample Input
    2 4 0 0 0 1 1 0 1 1 4 0 0 1 0 0 1 -1 -1
     
    Sample Output
    1 0
     
    题意:给出700个点,求可以构成多少个凸四边形,如果暴力的话肯定会超时
      那么可以逆向思维,C4个四边形减去凹四边形即可
      只要一个三角形中有一个点就是一个凹四边形,但是暴力找三角形照样会超时
      那么久找一个点在多少个三角形中和最后统计的每个三角形中的点数的总数是一样的
      要想找一个点在多少个三角形中就可以找一个点没在多少个三角形中然后C3n个总共的三角形减去这个值即可
      用扫描线法找到其不再多少个三角形的时候,只要枚举每个点,以这个点为中心点的话,和其他每个点连线,找这个线的一侧的点数j , 其上面任选两个点即可构成一个不包含它的三角形
    所以就可以C2j 个三角形不包含它,所以先以中心点,将其他点按犄角排序,然后开始逆时针扫描另一侧不用扫描因为在线在转的时候回有扫到下侧的点的,要是考虑两侧的话所有的三角形会被算两遍,这样 枚举中心点是n 的复杂度,每次排序是logn 统计数目又是找点又是n 的,所以最后的复杂度就是n*(logn+n) 这样就不会超时了,起到了降维的作用
      下面是代码:
     1 #include <cstdio>
     2 #include <cmath>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 #define eps 1e-8
     7 #define pi acos(-1.0)
     8 #define N 750
     9 
    10 int n;
    11 
    12 struct point
    13 {
    14     double x, y;
    15     point(){}
    16     point(double _x, double _y ):x(_x), y(_y){}
    17 };
    18 
    19 point P[N];
    20 double ang[2*N];
    21 int main()
    22 {
    23     //printf("%d", 700*699*698/6);
    24    int T, n;
    25    scanf("%d", &T);
    26    while(T--)
    27    {
    28         scanf("%d", &n);
    29         for(int i = 0; i < n; i++)
    30             scanf("%lf %lf", &P[i].x, &P[i].y);
    31 
    32         long long ans = (long long)n*(n-1)*(n-2)*(n-3)/24;//C(n,4)
    33         for(int i = 0; i < n; i++)
    34         {
    35             long long cnt = (long long)(n-1)*(n-2)*(n-3)/6;//cnt记录包含i的三角形个数
    36 
    37             int c = 0;
    38             for(int j = 0; j < n; j++)
    39             {
    40                 if(i == j) continue;
    41                 ang[c++] = atan2(P[j].y-P[i].y, P[j].x - P[i].x);
    42             }
    43 
    44             sort(ang, ang+c);
    45             for(int j = c; j < 2*c; j++)
    46             {
    47                 ang[j] = ang[j-c] + 2*pi;
    48            //     printf("a--   %lf
    ", ang[j-c] * 180.0 /pi);
    49             }
    50            // puts("");
    51 
    52             int k = 1;
    53 
    54             //puts("haha");while(t < 1000000000) t++;
    55             for(int j = 0; j < c; j++)//不包含i的三角形
    56             {
    57                 while(ang[k] - ang[j] < pi) k++;
    58                 int d = k-j-1;
    59              //   printf("d = %d
    ", d);
    60                 if(d > 1) cnt -= d*(d-1)/2;
    61             }
    62 
    63             ans -= cnt;
    64         }
    65         printf("%I64d
    ",ans);
    66    }
    67    return 0;
    68 }
  • 相关阅读:
    团队-团队编程项目爬取豆瓣电影top250-代码设计规范
    团队编程项目作业2-团队编程项目开发环境搭建过程
    团队编程项目作业2-团队编程项目设计文档
    《结对-结对编项目作业名称-开发环境搭建过程》
    《20170912-构建之法:现代软件工程-阅读笔记》
    结对编程项目作业2-英文词频检测程序-设计文档
    个人-GIT使用方法
    阅读任务-阅读提问
    《团队-Python 爬取豆瓣电影top250-成员简介及分工》
    团队-爬取豆瓣电影TOP250-需求分析
  • 原文地址:https://www.cnblogs.com/shanyr/p/4688580.html
Copyright © 2011-2022 走看看