Mountains
Description
Octopus and Penguin love sports, especially the climb. They step on the most top building of Changsha to view the Yuelu Mountain in weekend and are attracted by the imposing landscape. However, they can't see the whole mountain because the building is not high enough. Please help them to calculate the total length of surface for mountain they can see.
Suppose Octopus and Penguin's coordinate is (0,h) and the mountain is composed by n points which satisfy: 1. All points' coordinates are equal to or larger than zero. 2. The first point is 0, it's coordinate is ( w 0, 0)( w 0 >= 0). 3. n points are listing in ascending sort by x-axis. 4. Odd points' y-axis is larger than the former one. 5. Even points' y-axis (except for 0 point) is small than the former one. Condition 3,4 and 5 is means for three nearby points ( w 2k, h 2k), ( w 2k+1, h 2k+1) and ( w 2k+2, h 2k+2)( k ∈ N *,2 k+2< n), satisfied w 2k < w 2k+1 < w 2k+2, h 2k+1 > h 2k and h 2k+2 < h 2k+1. 6. The last point is ( w n-1, 0). The figure below corresponding sample input one: Input
There are several test cases. For each case, the first line is two integers n (0<n<=1000) and h. Then n lines follow and each line is two integers x and y(0<=x,y<=1000) describe the coordinates of mountains. n=h=0 means end of the input.
Output
For each case, output the surface length of mountain they can see.
Sample Input 3 5 0 0 1 1 2 0 5 5 0 0 2 2 3 1 5 3 8 0 5 4 0 0 2 2 3 1 5 3 8 0 0 0 Sample Output 2.83 7.07 5.66 Source |
提示
题意:
给出一些山的坐标,数据保证以x轴从小到大的顺序给出,且起始点为(0,0),奇数点高度比前一个要小,偶数点高度比前一个大,再给出它们两个的看台高度h(坐标为(0,h))。求出它们所能看到山表面的长度。
思路:
一开始我一直用点积来判断是否会被遮挡,之后看了别人写的原来只要比较斜率(过看台的坐标和山每一点的直线,不包括原点),只要斜率比之前的大,就说明不会被阻挡,并更新斜率。
比较有技巧的一题。
最后倒数第二个点貌似不符合题意。
示例程序
Source Code
Problem: 3227 Code Length: 1172B
Memory: 420K Time: 16MS
Language: GCC Result: Accepted
#include <stdio.h>
#include <math.h>
struct point
{
double x,y;
}p[1000],s,t,mark;
double f(struct point a,struct point b)
{
return (b.y-a.y)/(b.x-a.x);
}
double dis(struct point a,struct point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct point line(struct point a,struct point b,struct point c,struct point d)
{
double A1,B1,C1,A2,B2,C2;
struct point q;
A1=b.y-a.y;
B1=a.x-b.x;
C1=a.y*b.x-a.x*b.y;
A2=d.y-c.y;
B2=c.x-d.x;
C2=c.y*d.x-c.x*d.y;
q.x=(B1*C2-B2*C1)/(A1*B2-A2*B1);
q.y=(A2*C1-A1*C2)/(A1*B2-A2*B1);
return q;
}
int main()
{
int n,i;
double sum,k;
scanf("%d %lf",&n,&s.y);
while(n!=0||s.y!=0)
{
s.x=0;
sum=0;
for(i=0;n>i;i++)
{
scanf("%lf %lf",&p[i].x,&p[i].y);
}
mark=p[0]; //需要记录没被阻挡的山顶,用于计算被阻挡后还能看见多少,这里初始化
for(i=1;n>i;i++)
{
if(i==1||f(s,p[i])>k) //i=1时初始化为k定位,后面开始比较
{
k=f(s,p[i]);
t=line(s,mark,p[i-1],p[i]); //视线过山顶所能看到最低的点
sum=sum+dis(t,p[i]);
mark=p[i];
}
}
printf("%.2f\n",sum);
scanf("%d %lf",&n,&s.y);
}
return 0;
}