1031 Fence

描述
在一些平地上有一个围栏围起来的区域。栅栏具有高度h并且在平面投影中它具有闭合折线(没有自交叉)的形式,其由其N个顶点的笛卡尔坐标(Xi,Yi)指定。在坐标(0,0)处,灯站在场地上。灯可以位于栅栏外部或内部,但不能位于其侧面,如下面的示例图片所示(细线所示部件未被灯照亮):

栅栏是完全黑色的,即它既不反射也不扩散,也不让光通过。研究和实验表明,以下定律表示落在该栅栏任意照明点上的光强度:
I0 = K / R
其中k是不依赖于所讨论的点的已知常数值,r是该点与平面投影中的灯之间的距离。具有宽度d1和高度h的无穷小窄垂直板的照射是
DI = I0 * |cosα| * DL * H
其中I0是栅栏板上的光强度,α是此时栅栏侧面的法线与灯的方向之间的平面投影角度。
您将编写一个程序,该程序将找到围栏的总照明,定义为所有照明板的照明总和。
输入
输入文件的第一行包含数字k,h和N,用空格分隔。 k和h是实常数。 N(3 <= N <= 100)是围栏的顶点数。然后是N行,每行包含两个实数Xi和Yi,用空格分隔。
输出
写入输出文件,栅栏的总照度四舍五入到小数点后的第二个数字。
样例输入
样例输入
0.5 1.7 3
1.0 3.0
2.0 -1.0
-4.0 -1.0
样例输出
5.34
#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;
}

来源:http://www.cppblog.com/guyuecanhui/archive/2010/08/24/88558.html

猜你喜欢

转载自www.cnblogs.com/sweet-ginger-candy/p/11518214.html