Codeforces Good Bye 2017 C. New Year and Curling 几何枚举

Posted ProLightsfxjh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Good Bye 2017 C. New Year and Curling 几何枚举相关的知识,希望对你有一定的参考价值。

C. New Year and Curling time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output

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
Note

The final positions of the disks will look as follows:

In particular, note the position of the last disk.


Source

Good Bye 2017

My Solution

题意:有n个半径为r的圆盘,从第1个到第n个圆盘,依次从y = 10^100的位置向y = 0直线运动,当到达y = 0时,或者碰到之前停止运动的圆盘则停止。这里相切也作为碰到。求每个圆盘最终所在位置的圆心坐标。

几何、枚举

对于考虑圆i时,扫一遍j = 1~i-1所以圆心所在的位置,dabs = abs(x[i] - x[j]);

如果它们的差dabs > 2*r 则它们不可能碰撞。否则ans[i] = max(ans[i], sqrt(4*r*r - dabs*dabs) + ans[j]);//ans[i]初始值为r。

sqrt(4*r*r - dabs*dabs)表示用勾股定理求(xj,yj)、(xi, yi)、(xi,yj)构成的直角三角形,求出yi - yj。

这样每次扫一遍,维护最大的ans[i]/*因为圆在第一次碰撞的时候就会停止*/,就是最终求出的圆i所在的位置。

此外这个等式包容了这三个点不能构成三角形时的情况。

时间复杂度 O(n^2)

空间复杂度 O(n)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <iomanip>
using namespace std;
typedef long long LL;
const LL MAXN = 1e3 + 8;

LL x[MAXN];
double ans[MAXN];

int main()

    #ifdef LOCAL
    freopen("c.txt", "r", stdin);
    //freopen("c.out", "w", stdout);
    LL T = 4;
    while(T--)
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);

    LL n, r, i, j;
    LL dabs;
    cin >> n >> r;
    for(i = 0; i < n; i++)
        cin >> x[i];
    
    for(i = 0; i < n; i++)
        ans[i] = r;
        for(j = 0; j < i; j++)
            dabs = abs(x[i] - x[j]);
            if(dabs > 2*r) continue;
            ans[i] = max(ans[i], sqrt(4*r*r - dabs*dabs) + ans[j]);
        
    
    for(i = 0; i < n; i++)
        if(i != 0) cout << " ";
        cout << fixed << setprecision(11) << ans[i];
    
    cout << endl;



    #ifdef LOCAL
    cout << endl;
    
    #endif // LOCAL
    return 0;

  Thank you!

                                                                                                                                             ------from ProLights

以上是关于Codeforces Good Bye 2017 C. New Year and Curling 几何枚举的主要内容,如果未能解决你的问题,请参考以下文章

codeforces Good bye 2016 E 线段树维护dp区间合并

Codeforces Good Bye 2016 E. New Year and Old Subsequence

Codeforces 1091 (Good Bye 2018)

Codeforces Good Bye 2016(部分题解)

Codeforces Good Bye 2018 F

[题解][Codeforces]Good Bye 2019 简要题解