Codeforces Round 906 (Div. 2) A-E1
Codeforces Round 906 (Div. 2) A-E1
A.Doremy's Paint 3
思路
如果任意两个相邻元素的和相同的话,那么就意味着,数组中数值不同的数的数量<=2吧。
如果不同的数在数组里出现次数之差>1,也不能让任意相邻的数满足题意
//
// Created by v8475 on 2023/10/29.
//
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
using namespace std;
void solve(){
int n;
cin >> n;
map<int,int> mp;
for(int i=0;i<n;i++){
int x;
cin >> x;
mp[x] ++;
}
if(mp.size()==1) puts("Yes");
else if(mp.size()==2&&abs(mp.begin()->second-mp.rbegin()->second)<=1) puts("Yes");
else puts("No");
}
int main(){
// freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
int T ;
cin >> T;
while(T--){
solve();
}
return 0;
}
B. Qingshan Loves Strings
思路
在出现重复的部分把 \(t\) 字符串给插进去再判断插入后的字符串是否是好字符串就行
//
// Created by v8475 on 2023/10/29.
//
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
using namespace std;
bool check(string str){
if(str.size()==1) return true;
for(int i=0;i<str.size()-1;i++){
if(str[i]==str[i+1]) return false;
}
return true;
}
void solve(){
int n , m;
cin >> n >> m;
string a , b;
cin >> a >> b;
string t = "";
if(a.size()==1){
t = a;
}
else {
for(int i=0;i<a.size();i++){
if(a[i-1]==a[i]) {
t += b;
t += a[i];
}
else t += a[i];
}
}
if(check(t)) puts("Yes");
else puts("No");
}
int main(){
// freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
int T ;
cin >> T;
while(T--){
solve();
}
return 0;
}
C.Qingshan Loves Strings 2
思路
\(B\) 题的加强版,先考虑清楚情况。
这次的 \(t\) 串变为了 \(01\)
\(s\) 串本来合法的情况下,一次都不需要
\(s\) 串不合法且首尾相同的情况下,怎么添加都实现不了
\(s\) 串不合法且长度为奇数的情况下,怎么添加都实现不了
因为good串完全不对称,添加满足下列条件(双指针 \(L\) , \(R\) )
- s[L]!=s[R] , 不相同,合法,下一个
- s[L]==s[R] , 相同 , 分情况讨论
- s[L]==0 , 往R后面插 \(01\) ,R也就到了插入后的 \(1\) 的位置了。
- s[L]==1 , 往L前面插 \(01\) ,L也就到了插入后的 \(0\) 的位置了。
//
// Created by v8475 on 2023/10/29.
//
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const int N = 100010;
char q[N];
int ans[N];
int hh , tt;
bool check(string str){
for(int i=0,j=str.size()-1;i<=j;j--){
if(str[i]==str[j]) return false;
}
return true;
}
void solve(){
int n;
cin >> n;
string s ;
cin >> s;
int cnt = 0;
if(check(s)){
cout << 0 << endl;
cout << endl;
return;
}
if(n%2){
puts("-1");
return;
}
hh = 700 , tt = 700;
q[hh] = s[0];
for(int i=1;i<s.size();i++) q[++tt] = s[i];
int l = 0 , r = 0;
while(hh<tt){
if(q[hh]!=q[tt]){
hh++ , tt--;
l++ , r++;
}
else {
if(q[hh]=='0'){
ans[++cnt] = l+tt-hh+1;
q[++tt] = '0';
q[++tt] = '1';
}
else {
ans[++cnt] = l;
q[--hh] = '1';
q[--hh] = '0';
}
}
if(cnt>300) break;
}
if(cnt<=300){
cout << cnt << endl;
for(int i=1;i<=cnt;i++) cout << ans[i] << " ";
cout << endl;
}
else puts("-1");
}
int main(){
// freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
int T ;
cin >> T;
while(T--){
solve();
}
return 0;
}
D.Doremy's Connecting Plan
思路
如果最后是实现全连通,那么所有的位置都能够与第一个位置相连通
即与第一个点连通的情况只是$$ \sum_{k \in S} a_k \ge 1\cdot j \cdot c, $$ 那么只需要稍微改一下不等式可以得到$$ \sum_{k \in S} a_k - 1\cdot j \cdot c\ge 0, $$
那么按照 $$a[j] - j\cdot c$$ 的值排序后依次与1连通即可。
//
// Created by v8475 on 2023/10/29.
//
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N = 100010;
bool cmp(PII a , PII b){
return (a.first-a.second) > (b.first-b.second);
}
void solve(){
int n , c;
cin >> n >> c;
vector<PII> a(n);
for(int i=0;i<n;i++){
int x;
cin >> x;
a[i] = {x,c*(i+1)};
}
int sum = a[0].first;
sort(a.begin(),a.end(),cmp);
bool fla = false;
for(int i=0;i<n;i++){
if(a[i].second == c) continue;
sum += a[i].first;
if(sum<a[i].second){
fla = true;
break;
}
}
if(!fla) puts("Yes");
else puts("No");
}
signed main(){
// freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
int T ;
cin >> T;
while(T--){
solve();
}
return 0;
}
E1. Doremy's Drying Plan (Easy Version)
思路
dp写不出来,试试贪心
先算出如果不去掉任意一天,有几个城市是dry
后面分情况:
-
删掉第k天,可以让x个城市dry,先存下
-
删掉某两天,可以让x个城市dry,再存下
细分下来 删掉某两天中的x个城市可以分成三个部分:
1. 删掉k1天,让x1个城市dry 2. 删掉k2天,让x2个城市dry 3. 删掉k1,k2天,让x3个城市dry
优先队列遍历每个城市,存下城市下雨的数量
1. 队列为空,则不会下雨
1. 队列为1,则有一天下雨
1. 队列为2,则有两天下雨,取出两天下雨覆盖的位置
最后遍历后两种情况取出两天最大的dry城市数量即可
//
// Created by v8475 on 2023/10/29.
//
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N = 200010;
int g[N];
vector<PII>s[N];
void solve(){
int n , m , k;
cin >> n >> m >> k;
vector<PII> a(m+1);
for(int i=1;i<=m;i++){
cin >> a[i].first >> a[i].second;
}
sort(a.begin()+1,a.end());
int ans = 0;
int l = 1;
map<int,int> mp;
map<PII,int> mp1;
priority_queue<PII,vector<PII>,greater<PII>> pq;
for(int i=1;i<=n;i++){
while(a[l].first==i&&l<=m){
pq.push({a[l].second,l});
l++;
}
while(pq.size()>0&&pq.top().first<i) pq.pop();
if(pq.size()==0) ans++;
else if(pq.size()==1) mp[pq.top().second]++;
else if(pq.size()==2){
auto[x,y] = pq.top();
pq.pop();
auto [xx,yy] = pq.top();
pq.push({x,y});
if(y>yy) swap(y,yy);
mp1[{y,yy}] ++;
}
}
int mn1 = 0 , mn2 = 0;
for(auto[x,y]:mp){
if(y>mn1){
mn2 = mn1;
mn1 = y;
}
else if(y>mn2){
mn2 = y;
}
}
int mn = mn1 + mn2;
for(auto[x,y]:mp1){
auto[x1,x2] = x;
mn = max(y+mp[x1]+mp[x2],mn);
}
cout << ans+mn << endl;
}
signed main(){
// freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
int T ;
cin >> T;
while(T--){
solve();
}
return 0;
}