问题描述
- 参赛者在不同阶段获得成绩,我们只取k−⌊k/4⌋k - ⌊k / 4⌋k−⌊k/4⌋个最高成绩作为参赛者的总成绩。
- 然后目前已经进行了nnn个阶段,但是不知道还会举行多少阶段会使第一个人的成绩大于等于第二个人的成绩。
思路分析
- 首先我们想想如何能使这个阶段数最少,那当然是让第一个人在接下来的阶段都是100100100分,第二个人都是000分,这样能保证阶段数最少。
- 那么我们怎么来实现呢?
- 在这里我们用的是前缀数组。
- 那么对于每次加阶段的时候,我们对于第一个人就是加上100100100,然后可能会减去前面的一些项,因为我们取的是k−⌊k/4⌋k - ⌊k / 4⌋k−⌊k/4⌋,那么每次使kkk是四的倍数时,我们就要删去前面一项,所以对于前缀数组,我们要的就是减去(n+i)/4(n + i) / 4(n+i)/4。
- 同理对于第二个人,我们是加上前面的几项,然后注意的是我们要的是(n+i)/4−i(n + i) / 4 - i(n+i)/4−i,因为和第一个一样,我们先到(n+i)/4(n + i) / 4(n+i)/4,然后由于加了iii个000,所以就是(n+i)/4−i(n + i) / 4 - i(n+i)/4−i。
代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn], b[maxn];
int suma[maxn], sumb[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(suma, 0, sizeof(suma));
memset(sumb, 0, sizeof(sumb));
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++)
{
cin >> b[i];
}
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + n);
for (int i = 1; i <= n; i++)
{
suma[i] = suma[i - 1] + a[i];
}
for (int i = 1; i <= n; i++)
{
sumb[i] = sumb[i - 1] + b[i];
}
for (int i = 0, sum1, sum2; i <= n; i++)
{
sum1 = i * 100 + suma[n] - suma[(n + i) / 4];
sum2 = i * 0 + sumb[n] - sumb[max(0, (n + i) / 4 - i)];
if (sum1 >= sum2)
{
cout << i << endl;
break;
}
}
}
return 0;
}