POJ 1031 Fence

POJ 1031 Fence
      网上都评价说这题不难,没什么算法,是道水题,可是我看了别人的代码后,感觉收获还是比较大的,就发了。
      这题先是求积分,高中物理都能搞定的,把dl=rdă代入就能求得I=ă*k*h,其中ă是每条边对原点夹的角,比如对边AB,它的ă就是<AOB。那么下面的问题就转化为整个图形对原点所夹的角的最大值,这里可能有个问题,比如对于一个螺旋型的Fence,原点在中心,那么可能求出的夹角大于2*PI,由于Fence是不能透光、反射、散射的,因此最大值只能为2*PI。又由于Fence不能经过原点,因此每条边的夹角在-PI~PI之间,这里求整个图形对原点所夹的角用了一个很强的方法,可以保证无论从哪个点开始算,只要是按顺序,它一定能求得最大的角度(我领悟了半天啊),而且min一定要初始化为0而不是2*PI等大于0的数,考虑下原点在图形内部的情况就知道了~~至于正确性,可以自已画个图就能理解了~~
      下面是我的实现代码,参考了网上代码~~

#include  < iostream >
#include 
< cmath >
using   namespace  std;
#define  PI 3.1415926
double  Angle(  double  x0,  double  y0,  double  x1,  double  y1 ) {
     
double a= atan2(y0,x0);
     
double b= atan2(y1,x1);
     
if( b-a> PI ) a+= 2*PI;    //将夹角映射到-PI~PI之间
     if( a-b> PI ) b+= 2*PI;
     
return a-b;
}


int  main() {
    
double h, k, x[101], y[101], max= 0, min= 0, sum= 0;
    
int n, i;
    scanf(
"%lf%lf%d",&k,&h,&n);
    
for( i= 0; i< n; i++ )
        scanf(
"%lf%lf",&x[i],&y[i]);
    x[n]
= x[0], y[n]= y[0];
    
for( i= 0; i< n; i++ ){      //精髓啊
        sum
+= Angle(x[i],y[i],x[i+1],y[i+1]);
        
if( sum< min )    min= sum;
        
if( sum> max )    max= sum;
        
if( max-min>= 2*PI ){
            max
= min+ 2*PI;
            
break;
        }

    }

    printf(
"%.2lf\n",(max-min)*k*h);
    
return 0;
}

你可能感兴趣的:(POJ 1031 Fence)