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 男神知道了自 ...
随机推荐
- Cisco中删除flash通过tftp服务器恢复
首先我们来看一下,Cisco路由器中的flash文件.通过show flash 命令来查看. 这时可以看到flash的版本是c1841-ipbasek9-mz.124-12.bin 下面我们删除这个f ...
- JDBC(用Eclipse操作数据库Oracle)的基础操作集合
JDBC: JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编 ...
- iOS - 文件操作(File Operating)
1. 沙盒 & NSData /*_______________________________获取沙盒路径_________________________________________* ...
- Transaction Script模式
Transcation Script模式适合于小项目,维护量小的项目. 好比cs文件中有一个主方法,调用了本文件中的其他方法,如果说不需要怎么维护的话Tranacation Script模式就可以了, ...
- Codevs 5126 推销员 2015年NOIP全国联赛普及组
5126 推销员 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死 ...
- ZigBee2006,2007,pro各个版本的区别
文章转载自http://home.eeworld.com.cn/my/space-uid-361439-blogid-224722.html
- [java学习笔记]java语言基础概述之内存的划分&堆和栈
1.内存的划分 1.寄存器 cpu处理 2.本地方法区 和所在系统相关 3.方法区 方法加载进内存,其实就是开辟了一块该方法的方法区 方法区中还可以有静态区,用于存放静态变量(类变量) 4.栈内存 5 ...
- 韩顺平细说Servlet视频系列之tom相关内容
韩顺平细说Servlet视频系列之tom相关内容 tomcat部署项目操作(注意:6.0版本以后的支持该操作,5.x版本需要另外配置?待验证!) 项目发布到tomcat的webapps文件下,然后启动 ...
- Android开发技巧:像QQ一样输入表情图像
EditText和TextView一样,也可以进行图文混排.所不同的是,TextView只用于显示图文混排效果,而EditText不仅可显示, 也可混合输入文字和图像,让我们先回顾一下图5.2所示的 ...
- Describe the difference between repeater, bridge and router.
中继器,路由器,网桥,网关的区别. 路由器:网络层设备,实现复杂的路径选择,控制IP包从源到目的地的路径:根据IP地址进行选路和转发IP数据包 中继器:物理层设备,物理信号的重新生成,对信号进行整形和 ...