AtCoder Regular Contest 185 總結

hhhqx發表於2024-10-16

前言

一題都不會,爽了。

[ARC185A] mod M Game 2

AB 每個人手上都有 \(n\) 張牌。點數分別為 \(1\)\(n\)A 先手。每次打出一張牌(一張牌不能重複使用),如果某人打出牌後,總和是 \(m\) 的倍數,這個人就輸了。

若牌出完了還沒人輸,則 A 勝。

多組資料,\(T \le 10^5\)\(n < m \le 10^9\)

做法

因為 \(n < m\),如果一人手上有兩張牌,他就不可能輸。

兩人至少一人手上有兩張牌,我們可以忽略他們具體是如何操作的,因為一定有一種方法達到這種狀態(畢竟兩人聰明絕頂)。

只用關心最後的狀態。

由於 A 先把自己的牌打完,如果 B 想要贏,就必須最後剩一個 \(x\),滿足 \(n(n+1)-x\)\(m\) 的倍數。

程式碼
#include <bits/stdc++.h>

using namespace std;
using LL = long long;
using PII = pair<int, int>;

int main(){
	ios::sync_with_stdio(0), cin.tie(0);
	int T; cin >> T;
	while(T--){
		LL n, m; cin >> n >> m;
		cout << (1 <= n * (n + 1) % m && n * (n + 1) % m <= n ? "Bob" : "Alice") << "\n";
	}
	return 0;
}

[ARC185B] +1 and -1

一個序列 \(A\),每次操作可以選擇 \(1 \le i < j \le n\) 然後 \(A_i\) 加一、\(A_j\) 減一。

問能否透過若干次操作使得 \(A\) 變為非降序列。注意是問能否

多組資料,\(T \le 2 \cdot 10^5\)\(\sum{n} \le 2 \cdot 10^5\)\(0 \le A_i \le 10^9\)

做法

\(s = \sum{A_i}\)。注意無論如何操作 \(s\) 都不會變。

我們需要找到一個最優的序列,不僅滿足不降,而且不能繼續操作。

\(s \bmod n = 0\),則序列就是 \(n\)\(\frac{s}{n}\)

擴充一下,則序列就是前面 \(n - s \bmod n\)\(\left\lfloor \frac{s}{n} \right\rfloor\),而後面是 \(s \bmod n\)\(\left\lfloor \frac{s}{n} \right\rfloor + 1\)

最優序列得到了,然後就是要判斷能否達成這個最優序列。設最優序列為 \(B\)

也就是需要每個 \(1 \le r \le n\) 都滿足 \(\sum\limits_{i=1}^{r}{B_i - A_i} \ge 0\)

程式碼
#include <bits/stdc++.h>

using namespace std;
using LL = long long;
using PII = pair<int, int>;

const int MAXN = 2e5 + 3;

int n;
LL a[MAXN], b[MAXN];

int main(){
	ios::sync_with_stdio(0), cin.tie(0);
	int T; cin >> T;
	while(T--){
		cin >> n;
		LL s = 0;
		for(int i = 1; i <= n; i++){
			cin >> a[i], s += a[i];
		}
		for(int i = 1; i <= n; i++) b[i] = s / n;
		for(int i = n - s % n + 1; i <= n; i++){
			b[i]++;
		}
		bool ooo = 1;
		s = 0;
		for(int i = 1; i <= n; i++){
			s += b[i] - a[i];
			ooo &= s >= 0;
		}
		cout << (ooo ? "Yes\n" : "No\n"); 
	}
	return 0;
}