题解 P1568 【赛跑】

2018-08-02 21:07:26


这题我耗了很久。主要的教训是,一开始视图以最优的方式解决这个问题,导致一些细小的bug很难调试

后来从最笨的方法入手,先 AC了, 然后调优, 最后发现优化后的代码比之前苦思冥想试图写的最优代码还要好看一些。

这题的主要难点是, 输入的速度、时间都是随机片段的,两人的时间点对不上!所以无法直接判断在某个时间点上谁前谁后。

最笨的方法是模拟每一秒的情况,依次耗尽各自的时间片段,计算每一秒每个人的位置。

这是最笨但是出错率最低的方法。 AC 之后可以尝试优化。

这时候优化也很容易了: 不必模拟每一秒的情况。 每次取 两人时间片段的最小值, 消耗掉就可以了。

#include <cstdio>
#include <algorithm>

using namespace std;

#define MAX_N 1001

int main()
{
    int n, m;
    int i, j;  // track step

    int s1[MAX_N], s2[MAX_N];  // speed
    int t1[MAX_N], t2[MAX_N];  // time interval

    scanf("%d %d", &n, &m);
    for (i = 1; i <= n; i++)
        scanf("%d %d", &s1[i], &t1[i]);
    for (i = 1; i <= m; i++)
        scanf("%d %d", &s2[i], &t2[i]);

    int t;  // min time interval
    int d1 = 0, d2 = 0;
    int state = -1, change = -1;
    for (i = 1, j = 1; i <= n && j <= m; )
    {
        t = min(t1[i], t2[j]);

        d1 += s1[i] * t;
        d2 += s2[j] * t;

        if (d1 != d2 && (d1 > d2) != state)
        {
            state = (d1 > d2);
            change++;
        }

        t1[i] -= t;
        t2[j] -= t;

        if (t1[i] == 0) ++i;
        if (t2[j] == 0) ++j;
    }
    if (change == -1) change = 0;
    printf("%d", change);
}