Codeforces Round 906 (Div. 2)
题目链接:Dashboard - Codeforces Round 906 (Div. 2) - Codeforces
A. Doremy’s Paint 3
题意:判断一个序列通过任意排列组合是否可以使相邻位的和相等。
思路:序列中不同的数最多为2,为2时需要不同的两数奇偶位交替出现,map记录一下数的种数,两种数数量的差最多为1,即奇数满足条件的情况。
AC code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 2e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n, m;
int gcd(int a, int b){
if(b) while((a %= b) && (b %= a));
return a + b;
}
int main(){
fast();
T = 1;
cin >> T;
while(T --){
map<int, int> mp;
cin >> n;
int cnt = 0;
for(int i = 0; i < n; i ++){
int x; cin >> x;
mp[x] ++;
}
if(mp.size() == 1) cout << "YES" << endl;
else if(mp.size() == 2){
int x = 0, y = 0;
for(auto i : mp){
if(!x)
x = i.second;
if(x)
y = i.second;
}
if(abs(x - y) <= 1) cout << "YES" << endl;
else cout << "NO" << endl;
}
else cout << "NO" << endl;
}
return 0;
}
B. Qingshan Loves Strings
题意:给出01字符串s和t,通过将t插入s的任意位置来使s的相邻位置字符不同。
思路:显然在s不成立的情况下,若要通过t让s成立,t首先要符合相邻位置字符不同,然后记录t的始末位置,遍历s串,若出现相邻字符相同的情况,判断t的始末字符与s中相邻字符是否相同,不同则插入,否则不可能。
AC code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 2e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n, m;
string s, t;
int gcd(int a, int b){
if(b) while((a %= b) && (b %= a));
return a + b;
}
int main(){
fast();
T = 1;
cin >> T;
while(T --){
cin >> n >> m;
cin >> s >> t;
int fs = 0, ft = 0;
for(int i = 1; i < n; i ++){
if(s[i] == s[i - 1]){
fs = 1; break;
}
}
for(int i = 1; i < m; i ++){
if(t[i] == t[i - 1]){
ft = 1; break;
}
}
if(!fs) cout << "YES" << endl;
else if(ft && fs) cout << "NO" << endl;
else{
char st = t[0], ed = t[m - 1];
int flag = 1;
for(int i = 1; i < n; i ++){
if(s[i] == s[i - 1]){
if(s[i - 1] != st && s[i] != ed) continue;
else{
flag = 0; break;
}
}
if(!flag) break;
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
}
return 0;
}
C. Qingshan Loves Strings 2
题意:给出01字符串s,一次操作为向s中插入一个01串t,是否可以在300次操作内使s串对称位置不相同。
思路:首先插入操作一次增加0和1的个数相等,所以初始状态的s中0和1的数量必须相等才能满足题意;在将01串插入s过程中,通过双指针从两边开始判断,当对称位置出现相同字符时进行插入操作,注意当相同字符为1时,在前缀指向字符前面插入01,为0时,在后缀指向字符的后面插入01,通过STL中的insert操作对s进行改变,同时右指针r需要向后移动两个位置保证时刻指向对称位置。
AC code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 2e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n;
string s;
int gcd(int a, int b){
if(b) while((a %= b) && (b %= a));
return a + b;
}
int main(){
fast();
T = 1;
cin >> T;
while(T --){
cin >> n >> s;
s = " " + s;
int flag = 1, l = 1, r = n;
while(l < r){
if(s[l] == s[r]){
flag = 0;
break;
}
l ++, r --;
}
int cnt = 0;
vector<int> ans;
for(int i = 1; i <= n; i ++){
if(s[i] == '1') cnt ++;
else cnt --;
}
if(cnt) cout << "-1" << endl;
else if(flag) cout << 0 << endl;
else{
string t = "01";
int l = 1, r = n;
while(l < r){
if(s[l] != s[r]){
l ++, r --;
continue;
}
if(s[l] == '0'){
ans.push_back(r);
s.insert(r + 1, t);
r += 2;
}
else{
ans.push_back(l - 1);
s.insert(l, t);
r += 2;
}
}
cout << ans.size() << endl;
for(auto i : ans)
cout << i << " ";
cout << endl;
}
}
return 0;
}
D. Doremy’s Connecting Plan
题意:将1到n的点变成一个联通块,每个点有自己的价值ai,点与点之间的连通条件为:两点间点的成本和大于两点下标的积*c
思路:最终所有点都可以连向1,若两个下标不为1的点可以连通,那么这两点任一点一定可以连接1(证明参考:Codeforces Round 906 (Div. 2) A~E1 - 知乎 (zhihu.com)),此时根据每个点连接1的剩余成本从大到小排序,初点价值为1的价值,按照排序向后判断,若不足以连接则直接跳出,否则将价值累加到初点。
AC code:
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 2e6+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n, c;
int root;
int gcd(int a, int b){
if(b) while((a %= b) && (b %= a));
return a + b;
}
signed main(){
fast();
T = 1;
cin >> T;
while(T --){
cin >> n >> c;
cin >> root;
vector<pair<int, PII>> a;
for(int i = 2; i <= n; i ++){
int x; cin >> x;
a.push_back({x - i * c, {x, i}});//单点到1的成本剩余
}
sort(a.begin(), a.end(), greater<pair<int, PII>>());
bool flag = 1;
for(auto i : a){
auto x = i.second;
if(root + x.first < x.second * c){
flag = 0;
break;
}
root += x.first;
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}