Mountains
Description ![]() 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;
}