前言
一題都不會,爽了。
[ARC185A] mod M Game 2
A
和 B
每個人手上都有 \(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;
}