题意:

  有一个连通器,由两个漏斗组成(关于漏斗的描述见描述)。

  现向漏斗中注入一定量的水,问最终水的绝对位置(即y轴坐标)

思路:

  总体来说分为3种情况。

  1.两个漏斗可能同时装有水。

  2.只可能a漏斗有水。

  3.只可能b漏斗有水。

  于是可以二分枚举y的坐标。

  关键在于对于某个y坐标来说,要求出新的交点,再求面积。

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <iostream>
using namespace std; const int maxn = ;
const double eps = 1e-;
const double inf = 999999999.99; struct Point{
double x,y;
}a[ maxn ],b[ maxn ],res[ maxn ],amid,bmid; double xmult( Point a,Point b,Point c ){
double ans = (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.x);
return ans;
} int cmp( Point a,Point b ){
if( a.x!=b.x ) return a.x<b.x;
else return a.y>b.y;
} double area( Point pnt[],int n ){
double ans = ;
for( int i=;i<n-;i++ ){
ans += xmult( pnt[],pnt[i],pnt[i+] );
}
return fabs( 0.5*ans );
} int main(){
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while( T-- ){
double aim;
double ansY = ;
scanf("%lf",&aim);
int n1,n2;
scanf("%d",&n1);
double ymax = inf;
int flag1 = -;
for( int i=;i<n1;i++ ){
scanf("%lf%lf",&a[i].x,&a[i].y);
if( ymax>a[i].y ){
ymax = a[i].y;
flag1 = i;
}
}
amid = a[ flag1 ];
scanf("%d",&n2);
ymax = inf;
int flag2 = -;
for( int i=;i<n2;i++ ){
scanf("%lf%lf",&b[i].x,&b[i].y);
if( ymax>b[i].y ){
ymax = b[i].y;
flag2 = i;
}
}
bmid = b[ flag2 ];
//input
double aYmin = min( a[].y,a[n1-].y );
double bYmin = min( b[].y,b[n2-].y );
//printf("aYmin = %lf bYmin = %lf\n",aYmin,bYmin);
double abYmax = max( aYmin,bYmin );
double abYmin = min( amid.y,bmid.y );
double L ,R ;
//printf("L = %lf , R = %lf \n",L,R);
int special = -;
if( aYmin<=bmid.y )//a is lower
{
special = ;
}
else if( bYmin<=amid.y )
{
special = ;
}
if( special==- ){
L = abYmin;
R = min( aYmin,bYmin );
while( L<R ){
double mid = (L+R)/2.0;
double sumArea = ;
/*******solve b******/
//printf("mid = %lf\n",mid);
if( mid>bYmin ){
int cnt = ;
double newY = bYmin;
int f = -;
for( int i=;i<n2;i++ ){
if( b[i].y<=newY ){
res[ cnt++] = b[ i ];
f = i;
}
else break;
}
if( f==- ){}
else{
Point tmp;
tmp.y = newY;
tmp.x = (b[ f+ ].x-b[ f ].x)*(newY-b[f].y)/(b[f+].y-b[f].y) + b[f].x;
res[ cnt++ ] = tmp;
}
sumArea += area( res,cnt );
}
else if( mid<=bmid.y ){}
else{
//printf("here\n");
int cnt = ;
int f = -;
for( int i=;i<n2;i++ ){
if( b[i].y<=mid ){
f = i;
break;
}
}
//printf("f = %d\n",f);
Point tmp;
tmp.y = mid;
tmp.x = b[f].x-( (b[f].x-b[f-].x)*(mid-b[f].y)/(b[f-].y-b[f].y) );
res[ cnt++] = tmp;
for( int i=f;i<n2;i++ ){
if( b[i].y<mid ){
res[ cnt++ ] = b[i];
f = i;
}
else break;
}
tmp.y = mid;
tmp.x = (b[ f+ ].x-b[ f ].x)*(mid-b[f].y)/(b[f+].y-b[f].y) + b[f].x;
res[ cnt++ ] = tmp;
//printf("cnt = %d\n",cnt);
sumArea += area( res,cnt );
}
//printf("sumarea = %lf \n",sumArea);
/********solve a *****/
if( mid>aYmin ){
int cnt = ;
double newY = aYmin;
int f = -;
for( int i=;i<n1;i++ ){
if( a[i].y<=newY ){
res[ cnt++] = a[ i ];
f = i;
}
else break;
}
if( f==- ){}
else{
Point tmp;
tmp.y = newY;
tmp.x = (a[ f+ ].x-a[ f ].x)*(newY-a[f].y)/(a[f+].y-a[f].y) + a[f].x;
res[ cnt++ ] = tmp;
}
sumArea += area( res,cnt );
}
else if( mid<=amid.y ){}
else{
int cnt = ;
int f = -;
for( int i=;i<n1;i++ ){
if( a[i].y<=mid ){
f = i;
break;
}
}
Point tmp;
tmp.y = mid;
tmp.x = a[f].x-( (a[f].x-a[f-].x)*(mid-a[f].y)/(a[f-].y-a[f].y) );
res[ cnt++] = tmp;
for( int i=f;i<n1;i++ ){
if( a[i].y<mid ){
res[ cnt++ ] = a[i];
f = i;
}
else break;
}
tmp.y = mid;
tmp.x = (a[ f+ ].x-a[ f ].x)*(mid-a[f].y)/(a[f+].y-a[f].y) + a[f].x;
res[ cnt++ ] = tmp;
sumArea += area( res,cnt );
}
//printf("sumarea2 = %lf\n\n\n",sumArea);
if( fabs(sumArea-aim)<=eps ){
ansY = mid;
break;
}
else if( sumArea>aim ){
R = mid-eps;
}
else {
L = mid+eps;
ansY = mid;
}
}
}//ab可能都同时都有水
else{
//printf("special = %d\n",special);
double sumArea = ;
if( special== ){//‘1’表示只有a会有水
double L = amid.y;
double R = aYmin;
while( L<R ){
double mid = (L+R)/2.0;
//printf("mid = %lf\n",mid);
int cnt = ;
int f = -;
for( int i=;i<n1;i++ ){
if( a[i].y<=mid ){
f = i;
break;
}
}
Point tmp;
tmp.y = mid;
tmp.x = a[f].x-( (a[f].x-a[f-].x)*(mid-a[f].y)/(a[f-].y-a[f].y) );
res[ cnt++] = tmp;
for( int i=f;i<n1;i++ ){
if( a[i].y<mid ){
res[ cnt++ ] = a[i];
f = i;
}
else break;
}
tmp.y = mid;
tmp.x = (a[ f+ ].x-a[ f ].x)*(mid-a[f].y)/(a[f+].y-a[f].y) + a[f].x;
res[ cnt++ ] = tmp;
sumArea += area( res,cnt );
//printf("cnt = %d\n",cnt);
//printf("sumarea = %lf\n",sumArea);
if( fabs(sumArea-aim)<=eps ){
ansY = mid;
break;
}
else if( sumArea>aim ) {
R = mid-eps;
}
else {
L = mid + eps;
ansY = L;
}
}
}
else{//'2'表示只有b会有水
double L = bmid.y;
double R = bYmin;
//printf("L = %lf,R = %lf\n",L,R);
while( L<R ){
double mid = (L+R)/2.0;
//printf("mid = %lf\n",mid);
int cnt = ;
int f = -;
for( int i=;i<n2;i++ ){
if( b[i].y<=mid ){
f = i;
break;
}
}
Point tmp;
tmp.y = mid;
tmp.x = b[f].x-( (b[f].x-b[f-].x)*(mid-b[f].y)/(b[f-].y-b[f].y) );
res[ cnt++] = tmp;
for( int i=f;i<n2;i++ ){
if( b[i].y<mid ){
res[ cnt++ ] = b[i];
f = i;
//printf("add : i = %d\n",i);
}
else break;
}
tmp.y = mid;
tmp.x = (b[ f+ ].x-b[ f ].x)*(mid-b[f].y)/(b[f+].y-b[f].y) + b[f].x;
res[ cnt++ ] = tmp;
//printf("cnt = %d\n",cnt);
sumArea += area( res,cnt );
if( fabs(sumArea-aim)<=eps ){
ansY = mid;
break;
}
else if( sumArea>aim ) {
R = mid-eps;
}
else {
L = mid + eps;
ansY = L;
}
}
}
}
printf("%.3lf\n",ansY);
}
return ;
}

EOJ-1708//POJ3334的更多相关文章

  1. BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币( dp )

    背包dp.. -------------------------------------------------------------------------------- #include< ...

  2. BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币

    1708: [Usaco2007 Oct]Money奶牛的硬币 Description 在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统 ...

  3. 1708: [Usaco2007 Oct]Money奶牛的硬币

    1708: [Usaco2007 Oct]Money奶牛的硬币 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 544  Solved: 352[Submi ...

  4. EOJ Monthly 2019.2 题解(B、D、F)

    EOJ Monthly 2019.2 题解(B.D.F) 官方题解:https://acm.ecnu.edu.cn/blog/entry/320/ B. 解题 单测试点时限: 2.0 秒 内存限制:  ...

  5. EOJ #276

    题面 感觉是个套路题,不是特别难(然而卡常 直接做不可做,改成算每个数的贡献 暴力的想法是容斥,即记录每个数在每行里的出现情况,从总方案中扣掉每一行都没选到这个数的方案,复杂度$O(n^3)$ 我们发 ...

  6. EOJ Monthly 2018.8 D. Delivery Service-树上差分(边权/边覆盖)(边权转点权)(模板题)

    D. Delivery Service 单测试点时限: 2.5 秒 内存限制: 512 MB EOJ Delivery Service Company handles a massive amount ...

  7. EOJ Problem #3249 状态压缩+循环周期+反向递推

    限量供应 Time limit per test: 4.0 seconds Time limit all tests: 4.0 seconds Memory limit: 256 megabytes ...

  8. EOJ Monthly 2018.7

    准备继续大学acm啦 又要开始愉快的码码码啦 第一次在华东师大OJ上面做题 看来EOJ上的积分体质是假的,我怎么一把上红??? A.数三角形 神tm的防AK题放在A,出题人很不友好啊... 先写了个暴 ...

  9. EOJ Monthly 2018.4

    A. ultmaster 的小迷妹们 Time limit per test: 2.0 seconds Memory limit: 256 megabytes ultmaster 男神和他的小迷妹们准 ...

  10. EOJ Monthly 2018.4 (E.小迷妹在哪儿(贪心&排序&背包)

    ultmaster 男神和小迷妹们玩起了捉迷藏的游戏. 小迷妹们都希望自己被 ultmaster 男神发现,因此她们都把自己位置告诉了 ultmaster 男神,因此 ultmaster 男神知道了自 ...

随机推荐

  1. mysql绿色版在windows系统中的启动

    mysql绿色版在windows系统中的启动 1.下载mysql免安装版 例如:mysql-5.7.11-winx64 2.修改配置文件,my-default.ini名称改为:my.ini,文件里面的 ...

  2. 承接VR/AR内容应用定制需求

    业务范围: 1 承接VR/AR内容应用定制需求: 教育培训.建筑建设.旅游体验.课件教学系统.交通车辆仿真,模拟驾驶系统.游戏等.2 各类最新VR设备,例如GearVR.HTC vive.Oculus ...

  3. (转)Flickr架构

    Flickr(http://www.flickr.com/ ) 是国外一个领先的图片分享网站,现在应该在yahoo门下,感觉yahoo还是有很多好东西,奈何资本要抛弃他了.这个轮回其实挺有意思的,起先 ...

  4. 模板:Set类

    头文件: #include <set> 定义: Set<string> set1; 添加: set1.insert("the"); 查询/获取元素 set1 ...

  5. web网页的表单排版利器--960css

    表单排版样式 960css 前言 一般web网页的表单排版,大家都习惯用table排版,自己需要根据实际需要去定义TR和TD,很多时候对于TD的高宽度.是否合并行,合并列,都要去做一些处理,这些都是比 ...

  6. Jquery-zTree的基本用法

    [简介] zTree 是利用 JQuery 的核心代码,实现一套能完成大部分常用功能的 Tree 插件 兼容 IE.FireFox.Chrome 等浏览器 在一个页面内可同时生成多个 Tree 实例 ...

  7. preventDefault()、stopPropagation()、return false 之间的区别

    “return false”之所以被误用的如此厉害,是因为它看起来像是完成了我们交给它的工作,浏览器不会再将我们重定向到href中的链接,表单也不会被继续提交,但这么做到底有什么不对呢? 可能在你刚开 ...

  8. nodejs npm install全局安装和本地安装的区别

    npm的包安装分为本地安装(local).全局安装(global)两种,从敲的命令行来看,差别只是有没有-g而已,比如:代码如下:复制代码npm install # 本地安装npm install - ...

  9. Catalyst揭秘 Day4 analyzer解析

    Catalyst揭秘 Day4 analyzer解析 今天继续解析catalyst,主要讲一下analyzer,在sql语句的处理流程中,analyzer是在sqlparse的基础上,把unresol ...

  10. ios 基于CAEmitterLayer的雪花,烟花,火焰,爱心等效果demo(转)

    转载自:http://blog.csdn.net/mad2man/article/details/16898369 分类: cocoa SDK2013-11-23 11:52 388人阅读 评论(0) ...