Codeforces Good Bye 2017 C. New Year and Curling(运用数学解析几何的知识判断)

题目:C. New Year and Curling
Carol is currently curling.
She has n disks each with radius r on the 2D plane.
Initially she has all these disks above the line y = 10100.
She then will slide the disks towards the line y = 0 one by one in order from 1 to n.
When she slides the i-th disk, she will place its center at the point (xi, 10100). She will then push it so the disk’s y coordinate continuously decreases, and x coordinate stays constant. The disk stops once it touches the line y = 0 or it touches any previous disk. Note that once a disk stops moving, it will not move again, even if hit by another disk.
Compute the y-coordinates of centers of all the disks after all disks have been pushed.
Input
The first line will contain two integers n and r (1 ≤ n, r ≤ 1 000), the number of disks, and the radius of the disks, respectively.
The next line will contain n integers x1, x2, ..., xn (1 ≤ xi ≤ 1 000) — the x-coordinates of the disks.
Output
Print a single line with n numbers. The i-th number denotes the y-coordinate of the center of the i-th disk. The output will be accepted if it has absolute or relative error at most 10 - 6.
Namely, let's assume that your answer for a particular value of a coordinate is a and the answer of the jury is b. The checker program will consider your answer correct if for all coordinates.

样例:
Example
Input
6 2
5 5 6 8 3 12
Output
2 6.0 9.87298334621 13.3370849613 12.5187346573 13.3370849613
(原题http://codeforces.com/contest...);

题意:第一行输入两个数,第一个表示圆的个数,这些圆都是相同的,第二个数表示圆的半径大小,第二行输入每个圆的圆心的横坐标,且第一个圆先放,后面依次放,即从圆心的横坐标这个放下去,到X轴停下或者碰到另一个圆停下,让输出最后每个圆的圆心的纵坐标;

思路:关键在于判断这次放下的圆是否会碰到之前所有放下的圆,所有就是根据半径与横坐标之差来进行判断;(注意点,用直径的平方减去横坐标的平方来判断其两圆心的距离是否达到了要相碰的条件)(之后再计算纵坐标的时候,有可能因为纵坐标之差导致不会再相碰了,这个也要再判断一下);

新技巧:这题因为涉及了直角坐标系,所以要用解析结合的一些知识(公式或者性质等)来整理思路判断,进而写出代码;

代码:

#include<stdio.h>
#include<math.h>

int main()
{
    double x[1005],y[1005],tag;
    int n,r,i,j;
    scanf("%d%d",&n,&r);
    for(i=0;i<n;i++)
        scanf("%lf",&x[i]);
    for(i=0;i<n;i++)
        y[i]=r;
    for(i=0;i<n;i++)
    {
        for(j=0;j<i;j++)
            if(0<=4.0*r*r-(x[i]-x[j])*(x[i]-x[j]))
            {
                tag=y[j]+sqrt(4.0*r*r-(x[i]-x[j])*(x[i]-x[j]));
                if(tag>y[i])
                    y[i]=tag;
            }
    }
    for(i=0;i<n;i++)
    {
        printf("%lf",y[i]);
        if(i!=n-1)
            printf(" ");
    }
    printf("\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值