Codeforces Round 906 (Div. 2)

在这里插入图片描述

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;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值