中南多校CSU1634: Aquarium Tank

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

目录

题意:传送门

 原题目描述在最下面。
 一个横放在桌面上的的棱柱,长为 h i g h ,侧面是多边形。给你这个多边形n个点的坐标,在桌子上的点纵坐标为0,问你倒入 v o l u m e 升水入容器,它的高是多少?

思路:

 二分高度 m i d 算新的多边形的面积,得出体积大小。
 就是原来多边形上高度大于 m i d 的点不要,小于 m i d 的都要,并且加入直线上纵坐标为 m i d 的点。

AC代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<cctype>
#include<string>
#include<cmath>
#include<bitset>
#include <time.h>
#include<cassert>
#define mme(a,b) memset((a),(b),sizeof((a)))
#define fuck(x) cout<<"* "<<x<<"\n"
#define all(x) (x).begin(),(x).end()
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const int N = 10000+5;
int ab(int x){return x<0?-x:x;}
int n,m;
double high,volume;
struct lp{
  double x,y;
  lp(){};
  lp(double a,double b){x=a,y=b;}
}cw[N];
lp operator +(lp A,lp B){return lp(A.x+B.x,A.y+B.y);}
lp operator -(lp A,lp B){return lp(A.x-B.x,A.y-B.y);}
double operator *(lp A,lp B){return A.x*B.x+A.y*B.y;}
double operator ^(lp A,lp B){return A.x*B.y-A.y*B.x;}
double cross2(lp A,lp B){return A.x*B.y-A.y*B.x;}
double cross3(lp A,lp B,lp C){return (B-A)^(C-A);}
double Leng(lp A,lp B){return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));}
double disToLine(lp P,lp A,lp B){return fabs(((B-A)^(P-A))/Leng(A,B));}
bool cmp1(lp a,lp b){
  double p = atan2(a.y,a.x),q=atan2(b.y,b.x);
  if(p==q)return a.x<b.x;
  return p>q;
}
bool cmp2(lp a,lp b){
  lp c=lp(0,0);
  double tmp = cross3(c,a,b);
  if(tmp==0)return a.x<b.x;
  return tmp>0;
}
struct Polygon{
  lp p[N];
  int cnt;
  double area(){
    if(cnt<3)return 0;
    double s=cross2(p[cnt],p[1]);
    for(int i=1;i<cnt;++i){
      s+=cross2(p[i],p[i+1]);
    }
    /*double s=0;
    int pre=cnt;
    for(int i=1;i<=cnt;++i){
      s+=cross2(p[pre],p[i]);
      pre=i;
    }*/
    return fabs(s/2);
  }
}pol;

lp get_point(lp a,lp b,double y){
  if(fabs(a.x-b.x)<eps) return lp(a.x,y);
  double k = (y-a.y)/(b.y-a.y);
  return lp((b.x-a.x)*k+a.x,a.y+k*(b.y-a.y));
}
double get_area(double y){
  int cnt=0,pre=n;
  for(int i=1;i<=n;++i){
    if((y-cw[pre].y)*(y-cw[i].y)<=0){
      pol.p[++cnt]=get_point(cw[pre],cw[i],y);
    }
    if(cw[i].y<y)pol.p[++cnt]=cw[i];
    pre=i;
  }
  pol.cnt=cnt;
  return pol.area();
}
int main(){
  while(~scanf("%d",&n)){
    scanf("%lf%lf",&high,&volume);
    volume*=1000;
    double high_max=0;
    for(int i=1;i<=n;++i){
      scanf("%lf%lf",&cw[i].x,&cw[i].y);
      high_max=max(high_max,cw[i].y);
    }
    double l=0.0,r=high_max,mid;
    while(r-l>eps){
      mid=(l+r)/2;
      if(get_area(mid)*high<volume)l=mid;
      else r=mid;
    }
    printf("%.2f\n", l);
  }
  return 0;
}


原题目描述:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/81347742