Codeforces 2023-2024 A-H

chenaknoip發表於2024-10-30

題面

A B C D E F G H

難度:紅 橙 黃 綠 藍 紫 黑 黑

題解

A

題目大意:輸入 \(a\)\(b\),解不等式 \(b - 2x \le a - x (0 \le x \le a)\),輸出 \(a - x_{min}\)

解題思路:移項,得 \(x \ge b - a\)

#include <bits/stdc++.h>
using namespace std;
int t, a, b;
int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &a, &b);
		if (a >= b) printf("%d\n", a);
		else {
			int x = b - a;
			if (x <= a) printf("%d\n", a - x);
			else printf("0\n");
		}
	}
	return 0;
}

B

洛谷上這道題的題意翻譯是我寫的。

題目大意:

本題有多組測試資料。
有一臺檸檬水自動售貨機。機器上有 \(n\) 個槽位和 \(n\) 個按鈕,每個槽位對應一個按鈕,但你並不知道每個按鈕對應的是哪個槽位。
當您按下第 \(i\) 個按鈕時,有兩種可能的事件:

  • \(i\) 號槽位有至少一瓶檸檬水,則其中一瓶檸檬水會從這個槽位裡掉下來,然後你會把它取走。
  • \(i\) 號槽位沒有檸檬水,則什麼都不會發生。

檸檬水下落速度很快,因此您看不清它從哪個槽位掉出。您只知道每個槽位中瓶裝檸檬水的數量 \(a_i(1 \le a_i \le 10^9)\)
您需要求出至少收到 \(k\) 瓶檸檬水的最小按按鈕次數。
資料保證機器中至少存在 \(k\) 瓶檸檬水。

題目分析:
貪心+排序。

定義“按鈕按空”表示:該按鈕按下若干次後,不再掉下檸檬水(即對應槽位中沒有檸檬水)。

設當前有檸檬水的槽位中,數量最少的槽位為 \(p\),顯然對於每個已知按下能掉出檸檬水的按鈕,至少需要按 \(a_p\) 次,才能使這些按鈕中存在“被按空”的按鈕。

因此考慮進行如下操作:找到所有有檸檬水的槽位中,數量最少的槽位的檸檬水數,設為 \(x\),然後對於所有“沒有被按空”的按鈕,每個分別按下 \(x\) 次。由於是最壞情況,下一個按鈕將“被按空”。此時標記這個按鈕,並在下一輪中不再按下它。

解題思路:
可以考慮從小到大對陣列 \(a\) 排序,再從小到大進行列舉,直到已經掉出的檸檬水數量達到 \(k\)

總時間複雜度 \(O(n \text{log} n)\)

注:寫下這篇題解時,作者想要練習一下堆的用法。

#include <bits/stdc++.h>
using namespace std;
long long n, k, a[200010];
priority_queue<long long, vector<long long>, greater<long long> > q;
int main() {
	long long t;
	scanf("%lld", &t);
	while (t--) {
		while (!q.empty()) q.pop();
		scanf("%lld%lld", &n, &k);
		for (long long i = 1; i <= n; i++) {
			scanf("%lld", &a[i]);
			q.push(a[i]);
		}
		long long tmpn = n, cnt = 0;
		long long ans = 0;
		while (true) {
			if ((q.top() - cnt) * tmpn >= k) {
				ans += k;
				break;
			}
			ans += (q.top() - cnt) * tmpn + 1;
			k -= (q.top() - cnt) * tmpn;
			tmpn--;
			cnt = q.top();
			q.pop();
		}
		printf("%lld\n", ans);
	}
	return 0;
}

C

相關文章