题目链接:[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; }