Codeforces Round 1023 (Div. 2) ABC
链接
Dashboard - Codeforces Round 1023 (Div. 2) - Codeforces
A
将数组a分成两组,使得gcd(b) != gcd(c)
思路
gcd(a,b) <= min(a,b)
求数组a的max,min
如果数组a都一样无解 (即max == min
否则有解:让是max的一组,不是max的放另一组
代码
粘一下题解的吧
#include <bits/stdc++.h>
using namespace std;int main(){int t; cin >> t;while (t--){int n; cin >> n;vector <int> a(n);for (int i = 0; i < n; i++){cin >> a[i];}int mn = *min_element(a.begin(), a.end());int mx = *max_element(a.begin(), a.end());if (mn == mx){cout << "No\n";continue;}cout << "Yes\n";for (int i = 0; i < n; i++){cout << (1 + (a[i] == mx)) << " \n"[i + 1 == n];}}return 0;
}
B 博弈+思维
思路
要满足max - min <= k,最优的就是取最大的减,tom先max --,再计算max - min,如果 > k,tom一开始就输了,
只要tom第一次能操作,则jeryy一定不会出现max - min > k( jerry也同样取max--),这样下来,输的情况就只有数组全为0;每次操作只会-1,只要计算sum,奇数tom赢,偶数Jerry赢
代码
void solve()
{cin >> n >> k;LL sum = 0;for (int i = 1;i <= n;i ++) {cin >> a[i];sum += a[i];}sort(a + 1,a + 1 + n);a[n] --;sort(a + 1,a + 1 + n);if (a[n] - a[1] > k) cout << "Jerry" << endl;else {if (sum & 1) cout << "Tom" << endl;else cout << "Jerry" << endl;}}
C 最大字段和+构造
思路
1.先求出每一段已知的a[i]的和sum,如果存在一段和>k,无解
如果存在sum == k,标记存在
2.如果a数组全为已知,且存在最大字段和 == k,有解;否则无解
3.此时每一段的sum都 <= k,且存在未知的a[i];找一个未知的a[i],将其置为 k - pre - suf,其他未知的a[i]=-inf;suf为最大的后缀,pre为最大的前缀
代码
const int N = 2e5 + 10;
const LL inf = 1e18;LL n,m,k;
// vector<LL> a;
LL a[N];
char s[N];void solve()
{cin >> n >> k;for (int i = 1;i <= n;i ++) cin >> s[i]; for (int i = 1;i <= n;i ++) cin >> a[i];LL sum = 0;bool hasK = false;LL c1 = 0;for (int i = 1;i <= n;i ++){if (s[i] == '0'){sum = 0;continue;}c1 ++;sum = max(sum,0LL) + a[i];//最大字段和if (sum > k){cout << "No" << endl;return;}else if (sum == k) hasK = true;}if (c1 == n)//全1{if (!hasK) cout << "No" << endl;else {cout << "Yes" << endl;for (int i = 1;i <= n;i ++) cout << a[i] << " ";cout << endl;}return;}for (int i = 1;i <= n;i ++){if (s[i] == '0'){LL l = i - 1,r = i + 1;LL suf = 0,pre = 0,t = 0;while(l >= 1 && s[l] == '1'){t += a[l];suf = max(suf,t);l --;}t = 0;while(r <= n && s[r] == '1'){t += a[r];pre = max(pre,t);r ++;}a[i] = k - suf - pre;cout << "Yes" << endl;for (int j = 1;j <= n;j ++){if (s[j] == '0')cout << (j == i ? a[j] : -inf) << " ";else cout << a[j] << " ";}cout << endl;return;}}
}