题意:

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

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

思路:

  总体来说分为3种情况。

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

  2.只可能a漏斗有水。

  3.只可能b漏斗有水。

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

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

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <algorithm>
  6. #include <iostream>
  7. using namespace std;
  8.  
  9. const int maxn = ;
  10. const double eps = 1e-;
  11. const double inf = 999999999.99;
  12.  
  13. struct Point{
  14. double x,y;
  15. }a[ maxn ],b[ maxn ],res[ maxn ],amid,bmid;
  16.  
  17. double xmult( Point a,Point b,Point c ){
  18. double ans = (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.x);
  19. return ans;
  20. }
  21.  
  22. int cmp( Point a,Point b ){
  23. if( a.x!=b.x ) return a.x<b.x;
  24. else return a.y>b.y;
  25. }
  26.  
  27. double area( Point pnt[],int n ){
  28. double ans = ;
  29. for( int i=;i<n-;i++ ){
  30. ans += xmult( pnt[],pnt[i],pnt[i+] );
  31. }
  32. return fabs( 0.5*ans );
  33. }
  34.  
  35. int main(){
  36. //freopen("out.txt","w",stdout);
  37. int T;
  38. scanf("%d",&T);
  39. while( T-- ){
  40. double aim;
  41. double ansY = ;
  42. scanf("%lf",&aim);
  43. int n1,n2;
  44. scanf("%d",&n1);
  45. double ymax = inf;
  46. int flag1 = -;
  47. for( int i=;i<n1;i++ ){
  48. scanf("%lf%lf",&a[i].x,&a[i].y);
  49. if( ymax>a[i].y ){
  50. ymax = a[i].y;
  51. flag1 = i;
  52. }
  53. }
  54. amid = a[ flag1 ];
  55. scanf("%d",&n2);
  56. ymax = inf;
  57. int flag2 = -;
  58. for( int i=;i<n2;i++ ){
  59. scanf("%lf%lf",&b[i].x,&b[i].y);
  60. if( ymax>b[i].y ){
  61. ymax = b[i].y;
  62. flag2 = i;
  63. }
  64. }
  65. bmid = b[ flag2 ];
  66. //input
  67. double aYmin = min( a[].y,a[n1-].y );
  68. double bYmin = min( b[].y,b[n2-].y );
  69. //printf("aYmin = %lf bYmin = %lf\n",aYmin,bYmin);
  70. double abYmax = max( aYmin,bYmin );
  71. double abYmin = min( amid.y,bmid.y );
  72. double L ,R ;
  73. //printf("L = %lf , R = %lf \n",L,R);
  74. int special = -;
  75. if( aYmin<=bmid.y )//a is lower
  76. {
  77. special = ;
  78. }
  79. else if( bYmin<=amid.y )
  80. {
  81. special = ;
  82. }
  83. if( special==- ){
  84. L = abYmin;
  85. R = min( aYmin,bYmin );
  86. while( L<R ){
  87. double mid = (L+R)/2.0;
  88. double sumArea = ;
  89. /*******solve b******/
  90. //printf("mid = %lf\n",mid);
  91. if( mid>bYmin ){
  92. int cnt = ;
  93. double newY = bYmin;
  94. int f = -;
  95. for( int i=;i<n2;i++ ){
  96. if( b[i].y<=newY ){
  97. res[ cnt++] = b[ i ];
  98. f = i;
  99. }
  100. else break;
  101. }
  102. if( f==- ){}
  103. else{
  104. Point tmp;
  105. tmp.y = newY;
  106. tmp.x = (b[ f+ ].x-b[ f ].x)*(newY-b[f].y)/(b[f+].y-b[f].y) + b[f].x;
  107. res[ cnt++ ] = tmp;
  108. }
  109. sumArea += area( res,cnt );
  110. }
  111. else if( mid<=bmid.y ){}
  112. else{
  113. //printf("here\n");
  114. int cnt = ;
  115. int f = -;
  116. for( int i=;i<n2;i++ ){
  117. if( b[i].y<=mid ){
  118. f = i;
  119. break;
  120. }
  121. }
  122. //printf("f = %d\n",f);
  123. Point tmp;
  124. tmp.y = mid;
  125. tmp.x = b[f].x-( (b[f].x-b[f-].x)*(mid-b[f].y)/(b[f-].y-b[f].y) );
  126. res[ cnt++] = tmp;
  127. for( int i=f;i<n2;i++ ){
  128. if( b[i].y<mid ){
  129. res[ cnt++ ] = b[i];
  130. f = i;
  131. }
  132. else break;
  133. }
  134. tmp.y = mid;
  135. tmp.x = (b[ f+ ].x-b[ f ].x)*(mid-b[f].y)/(b[f+].y-b[f].y) + b[f].x;
  136. res[ cnt++ ] = tmp;
  137. //printf("cnt = %d\n",cnt);
  138. sumArea += area( res,cnt );
  139. }
  140. //printf("sumarea = %lf \n",sumArea);
  141. /********solve a *****/
  142. if( mid>aYmin ){
  143. int cnt = ;
  144. double newY = aYmin;
  145. int f = -;
  146. for( int i=;i<n1;i++ ){
  147. if( a[i].y<=newY ){
  148. res[ cnt++] = a[ i ];
  149. f = i;
  150. }
  151. else break;
  152. }
  153. if( f==- ){}
  154. else{
  155. Point tmp;
  156. tmp.y = newY;
  157. tmp.x = (a[ f+ ].x-a[ f ].x)*(newY-a[f].y)/(a[f+].y-a[f].y) + a[f].x;
  158. res[ cnt++ ] = tmp;
  159. }
  160. sumArea += area( res,cnt );
  161. }
  162. else if( mid<=amid.y ){}
  163. else{
  164. int cnt = ;
  165. int f = -;
  166. for( int i=;i<n1;i++ ){
  167. if( a[i].y<=mid ){
  168. f = i;
  169. break;
  170. }
  171. }
  172. Point tmp;
  173. tmp.y = mid;
  174. tmp.x = a[f].x-( (a[f].x-a[f-].x)*(mid-a[f].y)/(a[f-].y-a[f].y) );
  175. res[ cnt++] = tmp;
  176. for( int i=f;i<n1;i++ ){
  177. if( a[i].y<mid ){
  178. res[ cnt++ ] = a[i];
  179. f = i;
  180. }
  181. else break;
  182. }
  183. tmp.y = mid;
  184. tmp.x = (a[ f+ ].x-a[ f ].x)*(mid-a[f].y)/(a[f+].y-a[f].y) + a[f].x;
  185. res[ cnt++ ] = tmp;
  186. sumArea += area( res,cnt );
  187. }
  188. //printf("sumarea2 = %lf\n\n\n",sumArea);
  189. if( fabs(sumArea-aim)<=eps ){
  190. ansY = mid;
  191. break;
  192. }
  193. else if( sumArea>aim ){
  194. R = mid-eps;
  195. }
  196. else {
  197. L = mid+eps;
  198. ansY = mid;
  199. }
  200. }
  201. }//ab可能都同时都有水
  202. else{
  203. //printf("special = %d\n",special);
  204. double sumArea = ;
  205. if( special== ){//‘1’表示只有a会有水
  206. double L = amid.y;
  207. double R = aYmin;
  208. while( L<R ){
  209. double mid = (L+R)/2.0;
  210. //printf("mid = %lf\n",mid);
  211. int cnt = ;
  212. int f = -;
  213. for( int i=;i<n1;i++ ){
  214. if( a[i].y<=mid ){
  215. f = i;
  216. break;
  217. }
  218. }
  219. Point tmp;
  220. tmp.y = mid;
  221. tmp.x = a[f].x-( (a[f].x-a[f-].x)*(mid-a[f].y)/(a[f-].y-a[f].y) );
  222. res[ cnt++] = tmp;
  223. for( int i=f;i<n1;i++ ){
  224. if( a[i].y<mid ){
  225. res[ cnt++ ] = a[i];
  226. f = i;
  227. }
  228. else break;
  229. }
  230. tmp.y = mid;
  231. tmp.x = (a[ f+ ].x-a[ f ].x)*(mid-a[f].y)/(a[f+].y-a[f].y) + a[f].x;
  232. res[ cnt++ ] = tmp;
  233. sumArea += area( res,cnt );
  234. //printf("cnt = %d\n",cnt);
  235. //printf("sumarea = %lf\n",sumArea);
  236. if( fabs(sumArea-aim)<=eps ){
  237. ansY = mid;
  238. break;
  239. }
  240. else if( sumArea>aim ) {
  241. R = mid-eps;
  242. }
  243. else {
  244. L = mid + eps;
  245. ansY = L;
  246. }
  247. }
  248. }
  249. else{//'2'表示只有b会有水
  250. double L = bmid.y;
  251. double R = bYmin;
  252. //printf("L = %lf,R = %lf\n",L,R);
  253. while( L<R ){
  254. double mid = (L+R)/2.0;
  255. //printf("mid = %lf\n",mid);
  256. int cnt = ;
  257. int f = -;
  258. for( int i=;i<n2;i++ ){
  259. if( b[i].y<=mid ){
  260. f = i;
  261. break;
  262. }
  263. }
  264. Point tmp;
  265. tmp.y = mid;
  266. tmp.x = b[f].x-( (b[f].x-b[f-].x)*(mid-b[f].y)/(b[f-].y-b[f].y) );
  267. res[ cnt++] = tmp;
  268. for( int i=f;i<n2;i++ ){
  269. if( b[i].y<mid ){
  270. res[ cnt++ ] = b[i];
  271. f = i;
  272. //printf("add : i = %d\n",i);
  273. }
  274. else break;
  275. }
  276. tmp.y = mid;
  277. tmp.x = (b[ f+ ].x-b[ f ].x)*(mid-b[f].y)/(b[f+].y-b[f].y) + b[f].x;
  278. res[ cnt++ ] = tmp;
  279. //printf("cnt = %d\n",cnt);
  280. sumArea += area( res,cnt );
  281. if( fabs(sumArea-aim)<=eps ){
  282. ansY = mid;
  283. break;
  284. }
  285. else if( sumArea>aim ) {
  286. R = mid-eps;
  287. }
  288. else {
  289. L = mid + eps;
  290. ansY = L;
  291. }
  292. }
  293. }
  294. }
  295. printf("%.3lf\n",ansY);
  296. }
  297. return ;
  298. }

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. MyEclipse SVN 插件

    一.下载SVN插件subclipse 下载地址:http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240 在打开的网 ...

  2. 第五篇、微信小程序-swiper组件

    常用属性: 效果图: swiper.wxml添加代码: <swiper indicator-dots="{{indicatorDots}}" autoplay="{ ...

  3. HTML+CSS学习笔记(1) - Html介绍

    HTML+CSS学习笔记(1) - Html介绍 1.代码初体验,制作我的第一个网页 <!DOCTYPE HTML> <html> <head> <meta ...

  4. Exploit搭建

    1,三连下小水管真是慢.去洗澡先. 2,环境变量Path里添加Python安装目录.直接cd到git下来的目录运行sqlmap.py 更新sqlmap,sqlmap.py –update 或 git ...

  5. 引用、return

    C语言中没有引用,引用(reference)是c++对c语言的重要扩充.通俗点说,引用就是“起别名”.比如变量data,和它的引用 RefData.虽然名字不同,但是操作他们的时候,都操作的是相同的内 ...

  6. GDB 进行调试 使用心得

    GDB 进行调试 使用心得 转 1: 对于在应用程序中加入参数进行调试的方法:   直接用 gdb app -p1 -p2 这样进行调试是不行的.   需要像以下这样使用:    #gdb app   ...

  7. 在.NET连接MySQL以及封装好的MySQLHelper.cs

    1.首先上MySQL网站下驱动:http://www.mysql.com/products/connector/ 2.安装下载的安装包 3.我们在Visual Studio里创建一个Web Appli ...

  8. 长安CS15_手动——16款

    一.输入数据 1.CAN总线描述:位置,颜色,速率,总线类型 1)位置:OBD 2)颜色:3) 速率:500k 4)总线类型:HSCAN 5)测试时间:2016.5.4 2.车辆特征 1)排量:1.5 ...

  9. mysql 的 存储结构(储存引擎)

    1 MyISAM:这种引擎是mysql最早提供的.这种引擎又可以分为静态MyISAM.动态MyISAM 和压缩MyISAM三种:    静态MyISAM:如果数据表中的各数据列的长度都是预先固定好的, ...

  10. 统计网卡TX(发送)RX(接受)流量脚本

    显示网卡流量的方法蛮多,一般我们可以通过dstat来查看,但dstat不一定所有的机器都有安装.而我们知道,通过ifconfig可以看到某一网卡发送与接收的字节数,所以我们可以写一个脚本来统计一下. ...