[CodeForces 579C]A Problem about Polyline[数学]

题目链接:[CodeForces 579C]A Problem about Polyline[数学]

题意分析:

给出一条过点(0, 0) – (x, x) – (2x, 0) – (3x, x) – (4x, 0) – ... - (2kx, 0) – (2kx + x, x) – ....的折线,再给出点(a,b),问经过点(a,b)的折线中,x最小是多少?如果没有折线经过(a, b)则输出-1。答案精确到小数点后9位。

解题思路:

考虑到平移直线,最终只涉及到两条直线。斜率分别为1和-1。

它们的通式分别为:y = x - 2*n*x0 和 y = -x + 2*n*x0 (n为正整数,x0是题目中提到的x)

由于折线要过点(a, b)所以,x的大小至少要为b,不为b怎么可能能过(a,b)点 = =。

所以根据上面的式子就有:x0 = (x - y) / (2 * n) (x0 >= b && x > y) 和 x0 = (x + y) / (2 * n) (x0 >= b)。

个人感受:

昨天第二题以为是匹配的结果和要最优化,再加上刚开始除了第一题,其它题目分值一样。果断放弃了第二题做第三题。嘛,有得有失,c很快做出来了,b也在2小时多的时候搞定了XD。

具体代码如下:

#include<iostream>
#include<cstdio>
using namespace std;

const int INF = 0x7f7f7f7f;

int main()
{
    double a, b, ans = INF;
    scanf("%lf%lf", &a, &b);
    bool flag1 = 1, flag2 = 1;
    
    if (a >= b)                      // 第一种情况:y = x - 2 * n * x0
    {
        int n = (a - b) / 2.0 / b;
        if (a != b)                  // 这种情况下n有可能取值为0,要特判
            ans = (a - b) / 2.0 / n;
        else ans = b;
    }
    else flag1 = 0;
    
    int n = (a + b) / 2.0 / b;       // 第二种情况:y = -x + 2 * n * x0
    if (n < 1) flag2 = 0;
    else ans = min(ans, (a + b) / 2.0 / n);
    
    if (flag1 || flag2)
        printf("%.12f\n", ans);
    else printf("-1\n");
    return 0;
}



你可能感兴趣的:(数学)