计算几何 刷题记录

cfgym101808e floods

  • 题意:给出n个二维坐标描述一个折线段,水从y轴正向无穷远落下,不能穿过折线段,问你最后积水面积,n<1e5
  • 题解:先找到最高点,显然最高点左面的第二高的点往右划线一定与最高点那条折线有交点,递推的得到正解
  • 算面积直接梯形面积公式就行
  • 这个cf上测试点好像只有一个样例。。所以还要记得对拍,,,
  • 代码:
     1 #include <bits/stdc++.h>
     2 #define f(c,a,b) for(int c=a; c<=b; c++)
     3 #define nmax 100010
     4 
     5 using namespace std;
     6 double x[nmax], y[nmax], ax[nmax], ay[nmax];
     7 int mal[nmax], mar[nmax];
     8 
     9 double work(double px, double py, double qx, double qy, double y0){
    10     if(px == qx) return px; 
    11     return (px-qx)/(py-qy)*(y0-qy)+qx;
    12 }
    13 
    14 int main(){
    15     freopen("owo.txt","r",stdin);
    16     freopen("owo.out","w",stdout);
    17     int t;
    18     cin>>t;
    19     while(t--){
    20         int n;
    21         double sh=0, sl=0;
    22         cin >> n;
    23         f(i,1,n) {
    24             scanf("%lf%lf", &x[i], &y[i]);
    25             if(i != 1) sl+=(x[i]-x[i-1])*(y[i]+y[i-1]);
    26         }
    27         //cout<<"sl"<<sl<<endl;
    28         int max=y[1], id=1;
    29         f(i,2,n) {
    30             mal[i] = id;
    31             //cout<<id<<' ';
    32             if(y[i] > max){
    33                 id = i;
    34                 max=y[i];
    35             }
    36         }
    37         mal[1]=0;
    38         max = y[n], id=n;
    39         for(int i=n-1; i>=1; i--) {
    40             mar[i] = id;
    41             //cout<<id<<' ';
    42             if(y[i] > max){
    43                 id = i;
    44                 max=y[i];
    45             }
    46         }
    47         mar[n]=n+1;
    48         //f(i,1,n) cout<<mal[i]<<' '<<mar[i]<<endl;
    49         int cnt = nmax, pre = id;
    50         for(int i=mal[id]; i>0; i=mal[i]){ 
    51             //cout<<"i="<<i<<endl;
    52             int j;
    53             for(j=i; y[j]<=y[i]&&j<=id; j++);
    54             //cout<<j<<endl;
    55             for(int k=pre; k>=j; k--) { ax[--cnt] = x[k]; ay[cnt] = y[k]; }
    56             ay[--cnt] = y[i];
    57             ax[cnt] = work(x[j], y[j], x[j-1], y[j-1], y[i]) ;
    58             // cout<<ax[cnt]<<' '<<ay[cnt]<<endl; 
    59             pre = i;
    60         }
    61         ax[--cnt] = x[1]; ay[cnt] = y[1];
    62         //f(i,cnt,nmax-1) cout<<ax[i]<<' '<<ay[i]<<endl;
    63         f(i,cnt,nmax-2) sh += (ay[i]+ay[i+1])*(ax[i+1]-ax[i]);
    64         cnt = 0; 
    65         pre = id;
    66         for(int i=mar[id]; i<=n; i=mar[i]){ 
    67             //cout<<"i="<<i<<endl;
    68             int j;
    69             for(j=i; y[j]<=y[i]&&j>=id; j--);
    70             //cout<<"j="<<j<<endl;
    71             f(k,pre,j) { ax[++cnt] = x[k]; ay[cnt] = y[k]; }
    72             ay[++cnt] = y[i];
    73             ax[cnt] = work(x[j], y[j], x[j+1], y[j+1], y[i]);
    74             pre = i;
    75         }
    76         ax[++cnt] = x[n]; ay[cnt] = y[n];
    77         //f(i,1,cnt) cout<<ax[i]<<' '<<ay[i]<<endl;
    78         f(i,1,cnt-1) sh += (ay[i]+ay[i+1])*(ax[i+1]-ax[i]);
    79         printf("%.6lf\n", (sh-sl)/2 );
    80     }
    81     return 0;
    82 }
    😓

luoguP2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包

  • 代码:
     1 #include <bits/stdc++.h>
     2 #define nmax 10010
     3 #define eps 1e-9
     4 #define f(c,a,b) for (int c=a; c<=b; c++)
     5 
     6 using namespace std;
     7 struct P{
     8     double x, y;
     9     P(){};
    10     P(double _x, double _y):x(_x),y(_y){}
    11     bool operator < (const P a) const { return (a.x==x)?a.y>y:a.x>x; }
    12     P operator - (const P a) const { return P(a.x-x,a.y-y); }
    13     double len(){ return sqrt(x*x + y*y); }
    14 };
    15 typedef P V;
    16 P ps[nmax],po[nmax];
    17 int is=0, n;
    18 
    19 int sign(double x) { return x<-eps?-1:x>eps; }
    20 
    21 double times(P a, P b){ return a.x*b.y-a.y*b.x; }
    22 
    23 bool judge(V a, V b){ return times(a,b)<=0; }
    24 
    25 void andrew(){
    26     ps[++is]=po[1];
    27     f(i,2,n){
    28         while( is>=2 && !judge(ps[is]-ps[is-1], po[i]-ps[is]) ) is--;
    29         ps[++is]=po[i];
    30     }
    31     for(int i=n-1; i>=1; i--){
    32         while( is>=2 && !judge(ps[is]-ps[is-1], po[i]-ps[is]) ) is--;
    33         ps[++is]=po[i];
    34     }
    35 }
    36 
    37 int main(){
    38     freopen("owo.in","r",stdin);
    39     cin >> n;
    40     f(i,1,n) scanf("%lf%lf", &po[i].x, &po[i].y);
    41     sort(po+1,po+1+n);
    42     double ans = 0;
    43     andrew();
    44     f(i,2,is){
    45         P t=ps[i]-ps[i-1];
    46         ans+=t.len();
    47     } 
    48     printf("%.2lf", ans);
    49     return 0;
    50 }
    🛐

     

posted @ 2020-02-27 16:30  连昵称都不能重复  阅读(118)  评论(0编辑  收藏  举报