EOJ-1708//POJ3334
题意:
有一个连通器,由两个漏斗组成(关于漏斗的描述见描述)。
现向漏斗中注入一定量的水,问最终水的绝对位置(即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的更多相关文章
- BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币( dp )
背包dp.. -------------------------------------------------------------------------------- #include< ...
- BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币
1708: [Usaco2007 Oct]Money奶牛的硬币 Description 在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统 ...
- 1708: [Usaco2007 Oct]Money奶牛的硬币
1708: [Usaco2007 Oct]Money奶牛的硬币 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 544 Solved: 352[Submi ...
- 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 秒 内存限制: ...
- EOJ #276
题面 感觉是个套路题,不是特别难(然而卡常 直接做不可做,改成算每个数的贡献 暴力的想法是容斥,即记录每个数在每行里的出现情况,从总方案中扣掉每一行都没选到这个数的方案,复杂度$O(n^3)$ 我们发 ...
- EOJ Monthly 2018.8 D. Delivery Service-树上差分(边权/边覆盖)(边权转点权)(模板题)
D. Delivery Service 单测试点时限: 2.5 秒 内存限制: 512 MB EOJ Delivery Service Company handles a massive amount ...
- EOJ Problem #3249 状态压缩+循环周期+反向递推
限量供应 Time limit per test: 4.0 seconds Time limit all tests: 4.0 seconds Memory limit: 256 megabytes ...
- EOJ Monthly 2018.7
准备继续大学acm啦 又要开始愉快的码码码啦 第一次在华东师大OJ上面做题 看来EOJ上的积分体质是假的,我怎么一把上红??? A.数三角形 神tm的防AK题放在A,出题人很不友好啊... 先写了个暴 ...
- EOJ Monthly 2018.4
A. ultmaster 的小迷妹们 Time limit per test: 2.0 seconds Memory limit: 256 megabytes ultmaster 男神和他的小迷妹们准 ...
- EOJ Monthly 2018.4 (E.小迷妹在哪儿(贪心&排序&背包)
ultmaster 男神和小迷妹们玩起了捉迷藏的游戏. 小迷妹们都希望自己被 ultmaster 男神发现,因此她们都把自己位置告诉了 ultmaster 男神,因此 ultmaster 男神知道了自 ...
随机推荐
- 在win下面使用cdt+cygwin+cmake
在cygwin终端下面, cmake -G"Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug 当收获警告 Could ...
- 第五十篇、OC中常用的第三插件
1.UIViewController-Swizzled 当你接手一个新项目的时候,使用该插件,可以看到控制器的走向,当前控制是哪个,下一个跳转到哪里 2. 一个Xcode小插件,将Json直接转成模型 ...
- UITableView的编辑模式
UITableView可以分普通模式和Editing模式两种,这里我们着重讨论Editing模式,Editing模式中又分三种操作:Insert.Delete. Reallocted.Insert和D ...
- ICallbackEventHandler 接口实现回调处理功能
在最近的项目实现中遇到了一个问题 在数据处理的过程中,需要请求获取数据,再做处理之后,可以在页面及时获取数据 开始时,首先想到的到是写Ajax请求,但在做后续数据处理后,处理获取数据等操作,感觉实现起 ...
- (转)使用 Advanced Installer 打包 一键安装Web应用程序
使用 Advanced Installer 打包 一键安装Web应用程序 安装预览: 资源下载: 示例安装包 操作流程: 1.新建Asp.net Application. 2.设置 ...
- nodejs7.0 试用 async await
nodejs 7.0.0 已经支持使用 --harmony-async-await 选项来开启async 和 await功能. 在我看来,yield 和 async-await 都是在特定范围内实现了 ...
- javascript的setTimeout以及setInterval休眠问题。
前端码农们在做项目中时候,必定不可少的需要做到轮播效果.但是有些特殊的需求,比如: 需要做到第一个容器内容轮播滚动之后,第二个容器内部再轮播滚动,再第三个容器内容轮播滚动. 这时候我的一开始的思路是: ...
- lnmp全面优化集合nginx+mysql+php
lnmp的全名是linux+nginx+mysql+php,既然是全面优化那我们就从linux系统的选择入手.debian系统可以算是 linux各分支中做的比较突出的一类,连谷歌都抛弃linux订制 ...
- 自从用了Less 编写css,你比以前更快了~(sublime编译)
之所以用这个标题呢,主要是最近调侃杰伦太有意思了. 好吧,开个玩笑而已. 如果你了解过Less,并对之很熟悉,就不用往下看了. 如果你没用过,恭喜,这是一个入门级的教程,学会了它,可以为你节省10%的 ...
- STM8S003K3用Tim1的通道4输出20KHz的PWM波
void Init_pwm(){TIM1_DeInit(); TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, 800, 0x00);//250 TIM1_OC4In ...