廣州老字號,皇上皇香腸先生地道肉腸 3 斤 59.9 元
阿新 • • 發佈:2022-03-18
比賽連結:
https://atcoder.jp/contests/arc137/tasks
A - Coprime Pair
題目大意:
給了 \(l\) 和 \(r\),求出 \(x\) 和 \(y\),在滿足 \(l <= x < y <= r\),且 \(gcd(x, y) = 1\) 的情況下,使得 \(y - x\) 最大。
思路:
因為最多 1500 個數中就會有一個質數,所以直接暴力搜就可以了。
程式碼:
#include <bits/stdc++.h> using namespace std; #define LL long long LL l, r; int main(){ cin >> l >> r; for (LL i = r - l; i >= 0; -- i) //列舉長度 for (LL j = l; j + i <= r; ++ j) //列舉起點 if (__gcd(j, j + i) == 1){ cout << i << "\n"; return 0; } return 0; }
B - Count 1's
題目大意:
給定了一個只包含 0 和 1 的序列,現在可以翻轉一個連續區間的值,即將這個區間所有 0 變成 1,1 變成 0,問 1 的數量有多少種可能。
思路:
要統計出改變某一個區間最多能減少或增減多少個 1,就是求最大子段和,不過要求兩次,答案就是 1 加上增加和減少的最大值就可以了。
程式碼:
#include <bits/stdc++.h> using namespace std; int n, s, ans1, ans2; int main(){ ios::sync_with_stdio(false);cin.tie(0); cin >> n; vector <int> a(n); for (int i = 0; i < n; ++ i){ cin >> a[i]; if (!a[i]) a[i] = -1; s = max(s + a[i], a[i]); ans1 = max(ans1, s); } s = 0; for (int i = 0; i < n; ++ i){ a[i] = -a[i]; s = max(s + a[i], a[i]); ans2 = max(ans2, s); } cout << ans1 + ans2 + 1 << "\n"; return 0; }
C - Distinct Numbers
題目大意:
\(Alice\) 和 \(Bob\) 玩遊戲,有一個序列 \(A\),沒人操作一次,\(Alice\) 先手操作,每次可以選擇序列中最大的一個數,將其改為任意一個比自身小的非負數,但是序列中不能改為序列中已有的數,當有一個人不能操作之後,則另一人獲勝,兩人都足夠聰明,都採取最優策略。
思路:
記最大的元素記為 \(a\),次大的記為 \(b\)。
當只有一個元素可以移動,其它都已經在前面的時候,先手必勝,即滿足 \(b + 2 <= a\),如果 \(b + 1 = a\) 說明 \(a\) 也不能移動了。
還有兩個及以上的數要移動時,要看最大的兩個數之間的關係。如果剛開始就是 \(b + 1 = a\)
每個人都是最優,即每次都讓 \(a = b - 1\),那這時就要看移多少次才會移動到不能移的時候,判斷一下 \(a\) 和 \(n - 1\) 的奇偶性就可以了。
程式碼:
#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
int n;
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cin >> n;
vector <int> a(n);
for (int i = 0; i < n; ++ i)
cin >> a[i];
sort(all(a));
if (a[n - 2] + 2 <= a[n - 1]) cout << "Alice\n";
else{
int res = ( a[n - 1] - (n - 1) ) & 1;
if (res) cout << "Alice\n";
else cout << "Bob\n";
}
return 0;
}