CF-Codeforces Round #487 (Div. 2)-D-A Shade of Moonlight
描述
题解
数轴上 n n 个不重叠的云,给坐标,长度都是 ,有些云速度 1 1 ,有些云速度 ,现风速 w w ,问在风速不大于 时,有几对云可能在 0 0 相遇。
对于会相遇的云,肯定一个是 ,一个是 vi=−1 v i = − 1 ,所以我们首先可以根据 vi v i 将云分为两组,然后进行从小到大排序,接着枚举其中一组,去和另一组进行匹配。这里我们分组为 a[] a [ ] 和 b[] b [ ] ,分别表示 v=1 v = 1 与 v=−1 v = − 1 ,这里枚举 a[] a [ ] ,如果 a[i]>b[j] a [ i ] > b [ j ] ,那么他们是不可能相遇的,反之可能,但是必须满足 b[j]−a[i]+l2∗w>|b[j]−a[i]+l2+a[i]| b [ j ] − a [ i ] + l 2 ∗ w > | b [ j ] − a [ i ] + l 2 + a [ i ] | ,当我们匹配到这个云时,说明后边所有的云都是满足条件的,因为我们的云彩是按照位置从小到大进行排序的。当我们匹配到 j j 满足上述条件时,那么我们 ,如此这般,最后 ans a n s 即为正确结果。
代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1e5 + 10;
int n, l, w;
int a[MAXN], b[MAXN];
int main()
{
while (cin >> n >> l >> w)
{
long long ans = 0;
int x, v, cnt_a = 0, cnt_b = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &x, &v);
if (v == 1)
{
a[++cnt_a] = x;
}
if (v == -1)
{
b[++cnt_b] = x;
}
}
sort(a + 1, a + 1 + cnt_a);
sort(b + 1, b + 1 + cnt_b);
for (int i = 1, j = 1; i <= cnt_a; i++)
{
for (; j <= cnt_b; j++)
{
if (b[j] < a[i])
{
continue;
}
double tmp = b[j] - a[i] + (double)l;
double x = tmp / 2 + a[i];
if (x < 0)
{
x = -x;
}
if ((tmp / 2) * w > x)
{
break;
}
}
if (j > cnt_b)
{
break;
}
ans += cnt_b - j + 1;
}
printf("%lld\n", ans);
}
return 0;
}