poj 3277 Mountains

http://poj.org/problem?id=3227

這道題題意就是求登山遠望,看到山表面的長度。通過比較點所在直線的斜率來判斷線段是不是可以被看到。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 2000
using namespace std;

int n,h;
const double eps=1e-8;
int cmp(double x)
{
    if(fabs(x)<eps) return 0;
    if(x>0) return 1;
    return -1;
}
struct point
{
    double x,y;
    point() {}
    point(double a,double b):x(a),y(b) {}
} p[maxn];

double sqr(double x)
{
    return x*x;
}

double dis(point a,point b)
{
    return (sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)));
}

double det(point a,point b,point c,point d)
{
    return (b.x-a.x)*(d.y-c.y)-(b.y-a.y)*(d.x-c.x);
}

bool segem(point a,point b,point c,point d,point &e)
{
    double s1=det(a,b,a,c);
    double s2=det(a,b,a,d);
    e.x=(c.x*s2-d.x*s1)/(s2-s1);
    e.y=(c.y*s2-d.y*s1)/(s2-s1);
    return true;
}

double kk(point a,point b)
{
    return (b.y-a.y)/(b.x-a.x);
}
int main()
{
    while(scanf("%d%d",&n,&h)!=EOF)
    {
        if(n==0&&h==0) break;
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf",&p[i].x,&p[i].y);
        }
        point res;
        res.x=0;
        res.y=h;
        double sum=0;
        sum+=dis(p[0],p[1]);
        point key;
        key=p[1];
        for(int i=2; i<n; i++)
        {
            double k3=kk(res,p[i]);
            double k1=kk(p[i],p[i-1]);
            double k2=kk(res,key);
            if(k3-k2>eps)
            {
                if(k1-k2>=0)
                {
                    point e;
                    segem(res,key,p[i-1],p[i],e);
                    sum+=dis(e,p[i]);
                    key=p[i];
                }
            }
        }
        printf("%.2lf\n",sum);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章