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;
}