zoukankan      html  css  js  c++  java
  • EOJ-1708//POJ3334

    题意:

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

      现向漏斗中注入一定量的水,问最终水的绝对位置(即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 = 1005;
     10 const double eps = 1e-8;
     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 = 0;
     29     for( int i=1;i<n-1;i++ ){
     30         ans += xmult( pnt[0],pnt[i],pnt[i+1] );
     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 = 0;
     42         scanf("%lf",&aim);
     43         int n1,n2;
     44         scanf("%d",&n1);
     45         double ymax = inf;
     46         int flag1 = -1;
     47         for( int i=0;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 = -1;
     58         for( int i=0;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[0].y,a[n1-1].y );
     68         double bYmin = min( b[0].y,b[n2-1].y );
     69         //printf("aYmin = %lf bYmin = %lf
    ",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 
    ",L,R);
     74         int special = -1;
     75         if( aYmin<=bmid.y )//a is lower
     76         {
     77             special = 1;
     78         }
     79         else if( bYmin<=amid.y )
     80         {
     81             special = 2;
     82         }
     83         if( special==-1 ){        
     84             L = abYmin;
     85             R = min( aYmin,bYmin );
     86             while( L<R ){
     87                 double mid = (L+R)/2.0;
     88                 double sumArea = 0;
     89                 /*******solve b******/
     90                 //printf("mid = %lf
    ",mid);
     91                 if( mid>bYmin ){
     92                     int cnt = 0;
     93                     double newY = bYmin;
     94                     int f = -1;
     95                     for( int i=0;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==-1 ){}
    103                     else{
    104                         Point tmp;
    105                         tmp.y = newY;
    106                         tmp.x = (b[ f+1 ].x-b[ f ].x)*(newY-b[f].y)/(b[f+1].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
    ");
    114                     int cnt = 0;
    115                     int f = -1;
    116                     for( int i=0;i<n2;i++ ){
    117                         if( b[i].y<=mid ){
    118                             f = i;
    119                             break;
    120                         }
    121                     }
    122                     //printf("f = %d
    ",f);
    123                     Point tmp;
    124                     tmp.y = mid;
    125                     tmp.x = b[f].x-( (b[f].x-b[f-1].x)*(mid-b[f].y)/(b[f-1].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+1 ].x-b[ f ].x)*(mid-b[f].y)/(b[f+1].y-b[f].y) + b[f].x;
    136                     res[ cnt++ ] = tmp;
    137                     //printf("cnt = %d
    ",cnt);
    138                     sumArea += area( res,cnt );
    139                 } 
    140                 //printf("sumarea = %lf 
    ",sumArea);
    141             /********solve a *****/
    142                 if( mid>aYmin ){
    143                     int cnt = 0;
    144                     double newY = aYmin;
    145                     int f = -1;
    146                     for( int i=0;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==-1 ){}
    154                     else{
    155                         Point tmp;
    156                         tmp.y = newY;
    157                         tmp.x = (a[ f+1 ].x-a[ f ].x)*(newY-a[f].y)/(a[f+1].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 = 0;
    165                     int f = -1;
    166                     for( int i=0;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-1].x)*(mid-a[f].y)/(a[f-1].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+1 ].x-a[ f ].x)*(mid-a[f].y)/(a[f+1].y-a[f].y) + a[f].x;
    185                     res[ cnt++ ] = tmp;
    186                     sumArea += area( res,cnt );
    187                 }
    188                 //printf("sumarea2 = %lf
    
    
    ",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
    ",special);
    204             double sumArea = 0;
    205             if( special==1 ){//‘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
    ",mid);
    211                     int cnt = 0;
    212                     int f = -1;
    213                     for( int i=0;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-1].x)*(mid-a[f].y)/(a[f-1].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+1 ].x-a[ f ].x)*(mid-a[f].y)/(a[f+1].y-a[f].y) + a[f].x;
    232                     res[ cnt++ ] = tmp;
    233                     sumArea += area( res,cnt );
    234                     //printf("cnt = %d
    ",cnt);
    235                     //printf("sumarea = %lf
    ",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
    ",L,R);
    253                 while( L<R ){
    254                     double mid = (L+R)/2.0;
    255                     //printf("mid = %lf
    ",mid);
    256                     int cnt = 0;
    257                     int f = -1;
    258                     for( int i=0;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-1].x)*(mid-b[f].y)/(b[f-1].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
    ",i);
    273                         }
    274                         else break;
    275                     }
    276                     tmp.y = mid;
    277                     tmp.x = (b[ f+1 ].x-b[ f ].x)*(mid-b[f].y)/(b[f+1].y-b[f].y) + b[f].x;
    278                     res[ cnt++ ] = tmp;
    279                     //printf("cnt = %d
    ",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
    ",ansY);
    296     }
    297     return 0;
    298 }
    View Code
  • 相关阅读:
    ER图转关系模式, 强制参与和选择参与
    panoramio
    as3中flash的静态文本是可以直接访问的
    城市战3操作很失败
    20111120杭州天地行
    XNA 实用教程
    十、样式
    十三、“自己”的动画——图片转换
    十三、“导航”的动画——页面跳转
    十三、“自己”的动画——按钮
  • 原文地址:https://www.cnblogs.com/xxx0624/p/3762673.html
Copyright © 2011-2022 走看看