(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
目录
题意:传送门
原题目描述在最下面。
一个横放在桌面上的的棱柱,长为
,侧面是多边形。给你这个多边形n个点的坐标,在桌子上的点纵坐标为0,问你倒入
升水入容器,它的高是多少?
思路:
二分高度
算新的多边形的面积,得出体积大小。
就是原来多边形上高度大于
的点不要,小于
的都要,并且加入直线上纵坐标为
的点。
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;
}