Codeforces Round #550 (Div. 3)

A. Diverse Strings

非法情况:某个字符出现超过一次或者出现的字母不连续.


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)

int n;
string str;

int main()
{
	IOS;
	int __;
	cin >> __;
	while(__ -- )
	{
		cin >> str;
		map<char, int> mp;
		for(int i = 0; i < (int)str.size(); ++ i) mp[str[i]] ++;
		int flag = 0;
		vector<int> v;
		for(auto x : mp)
		{
			if(x.second > 1) flag = 1;
			v.push_back((int)x.first);
		}	
		sort(v.begin(), v.end());
		for(int i = 1; i < (int)v.size(); ++ i)
			if(v[i] - v[i - 1] != 1) flag = 1;
		if(!flag) cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	return 0;
}

B. Parity Alternated Deletions

假设奇数个数和偶数个数分别为(x)(y),答案即为数量较多的一组中的最小的(abs(y - x) - 1)项的和.


#include <bits/stdc++.h>
using namespace std;

int n;

int main()
{
	scanf("%d", &n);
	std::vector<int> v1, v2;
	for(int i = 1; i <= n; ++ i)
	{
		int x; scanf("%d", &x);
		if(x % 2) v1.push_back(x);
		else v2.push_back(x);
	}
	sort(v1.begin(), v1.end(), greater<int>());
	sort(v2.begin(), v2.end(), greater<int>());
	int res = 0;
	if(v1.size() > v2.size() + 1)
		for(int i = (int)v2.size() + 1; i < (int)v1.size(); ++ i)
			res += v1[i];
	else if(v2.size() > v1.size() + 1)
		for(int i = (int)v1.size() + 1; i < (int)v2.size(); ++ i)
			res += v2[i];
	printf("%d
", res);
	return 0;
}

C. Two Shuffled Sequences

某个数字出现次数大于2不合法,对于合法情况:排序后,只出现一次的全放入同一个序列中,出现两次的分别放入两个序列中,一个正序输出,一个倒序输出即可.


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int N = 2e5 + 20;

int n, a[N];

int main()
{
	IOS;
	cin >> n;
	map<int, int> mp;
	for(int i = 1; i <= n; ++ i) 
	{
		cin >> a[i];
		mp[a[i]] ++;
	}
	for(auto x : mp)
		if(x.second > 2) 
		{
			cout << "NO" << endl;
			return 0;
		}
	cout << "YES" << endl;
	sort(a + 1, a + n + 1);
	vector<int> v1, v2;
	v1.push_back(a[1]);
	for(int i = 2; i <= n; ++ i)
		if(a[i] == a[i - 1]) v2.push_back(a[i]);
		else v1.push_back(a[i]);
	cout << (int)v1.size() << endl;
	for(int i = 0; i < (int)v1.size(); ++ i)
		cout << v1[i] << ' ';
	cout << endl;
	cout << (int)v2.size() << endl;
	for(int i = (int)v2.size() - 1; i >= 0; -- i)
		cout << v2[i] << ' ';
	cout << endl;
	return 0;
}

D. Equalize Them All

找到出现最多的数字和它的某一个出现位置,然后向左向右扩展,把所有数字都改成出现最多的数字即可.


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int N = 2e5 + 20;

int n, a[N];

int main()
{
	IOS;
	cin >> n;
	map<int, int> mp;
	int id = 0, pos;
	for(int i = 1; i <= n; ++ i) 
	{
		cin >> a[i];
		mp[a[i]] ++;
		if(mp[a[i]] >= mp[id]) 
		{
			id = a[i];
			pos = i;
		}	
	}	
	cout << n - mp[id] << endl;
	for(int i = pos - 1; i >= 1; -- i)
	{
		if(a[i] == id) continue;
		if(a[i] > a[i + 1])
			cout << "2 " << i << " " << i + 1 << endl;
		else cout << "1 " << i << " " << i + 1 << endl;
		a[i] = id;
	}
	for(int i = pos + 1; i <= n; ++ i)
	{
		if(a[i] == id) continue;
		if(a[i] > a[i - 1]) 
			cout << "2 " << i << " " << i - 1 << endl;
		else cout << "1 " << i << " " << i - 1 << endl;
		a[i] = id;
	}
	return 0;
}

E. Median String

二十六进制下做加法和除2.


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)

int n;
string a, b;

int main()
{
	IOS;
	cin >> n;
	cin >> a >> b;
	std::vector<int> v;
	int t = 0;
	for(int i = a.size() - 1; i >= 0; -- i)
	{
		v.push_back((b[i] - 'a' + a[i] - 'a' + t) % 26);
		t = (b[i] - 'a' + a[i] - 'a' + t) / 26;
	}
	v[v.size() - 1] += 26 * t;
	for(int i = (int)v.size() - 1; i >= 0; -- i)
	{
		if(v[i] % 2 && i - 1 >= 0) v[i - 1] += 26;
		v[i] /= 2;
	}
	for(int i = (int)v.size() - 1; i >= 0; -- i)
		printf("%c", v[i] + 'a'); 
	puts("");
	return 0;
}

F. Graph Without Long Directed Paths

给每个点标记成入点和出点,相邻的点不能都是入点,也不能都是出点,然后对于输入的边,判断是否和出点到入点的方向相同即可.


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int N = 2e5 + 20;

int n, m;
int id[N], fist[N], idx;
struct Edge
{
	int to, nxt;
}line[N * 2];

void add(int x, int y)
{
	line[idx] = (Edge){y, fist[x]};
	fist[x] = idx ++;
} 

bool bfs()
{
	queue<int> q;
	q.push(1);
	id[1] = 0;
	while(!q.empty())
	{
		int u = q.front(); q.pop();
		for(int i = fist[u]; i != -1; i = line[i].nxt)
		{
			int v = line[i].to; 
			if(id[u] == id[v]) return 0;
			if(id[v] == -1) id[v] = (id[u] ^ 1), q.push(v);
		}
	}
	return 1;
}

int main()
{
	memset(fist, -1, sizeof fist);
	memset(id, -1, sizeof fist);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; ++ i)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		add(a, b);
		add(b, a);
	}
	if(bfs()) 
	{
		puts("YES");
		for(int i = 0; i < idx; i += 2) 
		{
			if(id[line[i].to] == 1 && id[line[i ^ 1].to] == 0) printf("0");
			else printf("1"); 
		}
		puts("");
	}
	else puts("NO");
	return 0;
}

G. Two Merged Sequences

维护一个递增,一个递减序列,判断当前元素可以放入哪个序列,如果只能放入一个序列,则放入该序列,如果放入两个序列都可以,则看下一个元素,如果下一个元素比当前元素大,则把这个元素放入递增序列,这样弱化了这个元素的作用,对后面的影响小,同理,如果下一个元素比当前元素小,则放入递减序列.


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 20;

int n, a[N];

int main()
{
	std::vector<int> res;
	int up = -1, down = INF;
	IOS;
	cin >> n;
	for(int i = 1; i <= n; ++ i) cin >> a[i];
	for(int i = 1; i <= n; ++ i)
	{
		if(a[i] <= up &&  a[i] >= down) { cout << "NO" << endl; return 0; } 
		if(a[i] > up && a[i] < down)
		{
			if(i + 1 <= n)
			{
				if(a[i + 1] == a[i])
				{
					up = a[i];
					down = a[i];
					res.push_back(0);
					res.push_back(1);
					i ++;
				}
				else if(a[i + 1] > a[i]) 
				{
					up = a[i];
					res.push_back(0);
				}
				else if(a[i + 1] < a[i])
				{
					down = a[i];
					res.push_back(1);
				}
			}
			else res.push_back(0);
		}
		else if(a[i] > up)
		{
			up = a[i];
			res.push_back(0);
		}
		else if(a[i] < down)
		{
			down = a[i];
			res.push_back(1);
		}
	}
	cout << "YES" << endl;
	for(auto x: res) cout << x << " ";
	cout << endl;
	return 0; 
}

2021.1.11

原文地址:https://www.cnblogs.com/ooctober/p/14264572.html