GDCPC 2024 Single Round Solution (PARTIAL)
GDCPC 2024 Single Round Solution (PARTIAL)
0. 感言
难。
题有 \(8\) 道,AC \(1\) 道。
身败名裂。
3. 乐乐买书
由题可设买 \(a\) 本黑书,\(b\) 本紫书,\(c\) 个糖果。
\[\begin{cases}
40a+39b+0.5c=n\\
a+b+c=n
\end{cases}
\]
上式减下式得
\[39a+38b=0.5c
\]
代入上式得
\[79a+77b=n
\]
求二元一次方程整数解数量即可。
时间复杂度 \(O(1)\)。
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
using ll = long long;
ll n, a, b, lw;
int main()
{
scanf("%lld", &n);
while (79 * a <= n and (n - 79 * a) % 77)
a++;
if (79 * a > n)
return puts("0"), 0;
b = (n - 79 * a) / 77;
printf("%lld\n", min(n / 77 - a + 1, b / 79 + 1));
}
7. 比赛
二分答案。
设初始所有比赛结果均为平局。
则胜负操作改为 \(+2/-1\),且操作上限为 \(k\),而不要求必须为 \(k\)。
二分答案 \(x\) ,则尽量增大包括 \(1\) 在内的 \((x+1)\) 个队伍的分值,减小其余 \((n-x-1)\) 个队伍的分值。
优先队列可做。
时间复杂度 \(O(nk\log^2 n)\)。
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n, k, a[N], tar, l, r;
using pii = pair<int, int>;
multiset<pii, greater<pii>> q;
inline bool check(int x)
{
decltype(q)().swap(q);
for (int i = 2; i <= n - x; i++)
{
q.insert({a[i], k});
}
if (!q.size())
return true;
for (int i = 1; i <= (x + 1) * k; i++)
{
if (!q.size())
return true;
auto tmp = *q.begin();
q.erase(q.begin());
tmp.first--, tmp.second--;
if (!tmp.second)
{
if (tmp.first > tar)
return false;
continue;
}
q.insert(tmp);
}
while (q.size() > 1 and q.begin()->first > tar)
{
auto t1 = *q.begin(), t2 = *prev(q.end());
q.erase(q.begin()), q.erase(prev(q.end()));
t1.first--, t1.second--, t2.first += 2, t2.second--;
if (t1.second)
q.insert(t1);
if (t2.first > tar)
return false;
if (t2.second)
{
q.insert(t2);
}
}
return q.empty() or q.begin()->first <= tar;
}
int main()
{
scanf("%d%d", &n, &k);
r = n - 1;
for (int i = 1; i <= n; i++)
{
scanf("%d", a + i);
a[i] += k;
}
tar = a[1] + 2 * k;
sort(a + 2, a + n + 1);
while (l < r)
{
int mid = (l + r) >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
printf("%d\n", r);
}