链接
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;
}
}
}