Codeforces Round #656 (Div. 3)

Codeforces Round #656 (Div. 3)

A. Three Pairwise Maximums

题意对于每组测试样例给出三个数x y z,你需要寻找三个数a, b, c使得x = max(a,b) y = max(a,c) z = max(b,c) 如果能找到则输出YES按任意顺序打印abc

题解:因为z是a、b和c三个整数中的最大值,并且它以两对出现(因此它在x、y和z中最多出现两次)。否则,答案就存在了,它可以是x,x和z,

代码:

#include <iostream>
using namespace std;

int main() {
	int t, x ,y ,z;
	cin >> t;
	while(t--) {
		bool Ture = false;
		int a = 0;
		int b = 0;
		int c = 0;
		cin >> x >> y >> z;
		if(x == y && y == z) {
			Ture = true;
			a = x;
			b = x;
			c = x;
		} else if(x == y && z < x) {
			Ture = true;
			a = x;
			b = z;
			c = z;
		} else if(x == z && y < x) {
			Ture = true;
			b = x;
			a = y;
			c = y;
			
		} else if(z == y && x < z) {
			Ture = true;
			c = z;
			b = x;
			a = x;
			
		}
		if(Ture) {
			cout << "YES" << endl;
			cout << a << " " << b << " " << c << endl;
		} else
		cout << "NO" << endl;
	}
	return 0;
} 

B. Restore the Permutation by Merger

题意:给出一个merge后的序列,求出以前的序列。

题解:遍历

代码:

#include <iostream>
#include <cstring>
using namespace std;

int a[55];
int b[150];
int num[55] = {0};

int main() {
	int t, n;
	cin >> t;
	while(t--) {
		memset(num,0,sizeof(num)); 
		int ans = 1;
		cin >> n;
		for(int i = 1; i <= 2*n; i++) {
			cin >> b[i];
			if(num[b[i]] == 0) {
				a[ans] = b[i];
				ans++;
				num[b[i]]++;
			}
		}
		for(int i = 1; i <= n; i++)
		cout << a[i] << " ";
		cout << endl;
	}
}

C - Make It Good

题意: 给出一个长度为n的序列,问你删除最少的前缀,使其变为一个good序列。所谓good序列是指通过删除a序列的头部或尾部添加到c序列,使得c序列单调不减。

代码

#include <iostream>
using namespace std;

int a[200005];

int main() {
	int t, n;
	cin >> t;
	while(t--) {
		cin >> n;
		for(int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		int head = 1;
		int tail = n;
		for(int i = n; i >= 1; i--) {
			if(a[i] > a[i-1]) {
				tail = i-1;
				break;
			}
		}
		for(int i = tail; i >= 1; --i) {
			if(a[i] < a[i-1]) {
				head = i;
				break;
			}
		}
		cout << head - 1 << endl;
	}
}

D - a-Good String

题解:二分

代码:

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;

char a[200005];

int solve(int l, int r, char c) {
	if(l == r)
	return a[l] != c;
	int mid = (l+r)/2;
	int left = 0;
	int right = 0;
	for(int i = l; i <= mid; i++) {
		if(a[i] != c)
		left++;
	}
	for(int i = mid + 1; i <= r; i++) {
		if(a[i] != c)
		right++;
	}
	return min(left + solve(mid+1,r,c+1),right+solve(l,mid,c+1));
}

int main() {
	int t, n;
	cin >> t;
	while(t--) {
		cin >> n;
		scanf("%s", a + 1);
		cout << solve(1,n,'a') << endl;
	}
	return 0;
} 

E - Directing Edges

题意:给你一个图,告诉你的边有点是有向的有些是无向的,把无向的边变成有向,如果形成的新的图有环,输出NO,否则输出YES。

题解:
先引入一个新的概念:拓扑排序详解

先建造一个只有有向边的拓扑排序。检查这些有向边组成的图中是否含有环。然后给无向边加方向只需要按照拓扑序顺序加方向即能保证不会出现环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值