• bzoj 2564 集合的面积


    Description

      对于一个平面上点的集合P={(xi,yi )},定义集合P的面积F(P)为点集P的凸包的面积。
      对于两个点集AB,定义集合的和为:
      A+B={(xiA+xjB,yiA+yjB ):(xiA,yiA )A,(xjB,yjB )B}
      现在给定一个N个点的集合A和一个M个点的集合B,求2F(A+B)
     

    Input

     第一行包含用空格隔开的两个整数,分别为NM
      第二行包含N个不同的数对,表示A集合中的N个点的坐标;
      第三行包含M个不同的数对,表示B集合中的M个点的坐标。

    Output

     一共输出一行一个整数,2F(A+B)

    Sample Input

    4 5
    0 0 2 1 0 1 2 0
    0 0 1 0 0 2 1 2 0 1

    Sample Output

    18
    数据规模和约定
      对于30%的数据满足N ≤ 200,M ≤ 200;
      对于100%的数据满足N ≤ 10^5,M ≤ 10^5,|xi|, |yi| ≤ 10^8。

    分别求出两个点集的凸包,然后贪心地加点就行。

    A和B凸包第一个点肯定在答案里

    然后贪心,如果A到了i,B到了j

    显然如果A[i+1]+B[j]比A[i]+B[j+1]更凸,也就是在右边,那么就i+1,否则j+1

    这样构造出的新凸包即为答案

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long lol; 
     8 struct point
     9 {
    10   lol x,y;
    11 }p[200001],s[3][200001],sta[1000001];
    12 int n,m,C,top;
    13 lol ans;
    14 lol cross(point a,point b)
    15 {
    16   return a.x*b.y-a.y*b.x;
    17 }
    18 point operator -(point a,point b)
    19 {
    20   return (point){a.x-b.x,a.y-b.y};
    21 }
    22 point operator +(point a,point b)
    23 {
    24   return (point){a.x+b.x,a.y+b.y};
    25 }
    26 bool cmp(point a,point b)
    27 {
    28   return (a.y<b.y)||(a.y==b.y&&a.x<b.x);
    29 }
    30 lol dist(point a)
    31 {
    32   return a.x*a.x+a.y*a.y;
    33 }
    34 bool cmp2(point a,point b)
    35 {
    36   lol t=cross((p[1]-a),(p[1]-b));
    37   if (t==0) return dist(p[1]-a)<dist(p[1]-b);
    38   return t>0;
    39 }
    40 int graham(int N,int c)
    41 {int i;
    42   int C=c;
    43   sort(p+1,p+N+1,cmp);
    44   sort(p+2,p+N+1,cmp2);
    45   top=0;
    46   s[c][++top]=p[1];s[c][++top]=p[2];
    47   for (i=3;i<=N;i++)
    48     {
    49       while (top>1&&cross(p[i]-s[c][top-1],s[c][top]-s[c][top-1])>=0) top--;
    50       ++top;
    51       s[c][top]=p[i];
    52     }
    53   return top;
    54 }
    55 int main()
    56 {int i,j;
    57   cin>>n>>m;
    58   for (i=1;i<=n;i++)
    59     {
    60       scanf("%lld%lld",&p[i].x,&p[i].y);
    61     }
    62   n=graham(n,1);
    63   for (i=1;i<=m;i++)
    64     {
    65       scanf("%lld%lld",&p[i].x,&p[i].y);
    66     }
    67   m=graham(m,2);
    68   sta[top=1]=s[1][1]+s[2][1];
    69   for (i=1,j=1;i<=n||j<=m;)
    70     {
    71       point x=s[1][(i-1)%n+1]+s[2][j%m+1],y=s[1][i%n+1]+s[2][(j-1)%m+1];
    72       if (cross(x-sta[top],y-sta[top])>=0)
    73     sta[++top]=x,j++;
    74       else sta[++top]=y,i++;
    75     }
    76   for (i=2;i<top;i++)
    77     ans+=cross(sta[i]-sta[1],sta[i+1]-sta[1]);
    78   printf("%lld",ans);
    79 }
  • 相关阅读:
    SIFT,SURF,ORB,FAST,BRISK 特征提取算法比较
    OpenCV 4.2.0 编译成功日志(Mac)
    Ceres Solver Bibliography
    Linux下重启就需要重新激活eth0的解决办法(ifup eth0)
    PS(光影魔术手)
    软件项目开发各阶段文档模板(参考)
    敏捷、瀑布开发模式
    QA
    QC
    会计人必知的实务基础知识
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8276751.html
Copyright © 2020-2023  润新知