Codeforces Round #656 (Div. 3) A、B、C、D题解

CF在两次unrate之后终于恢复正常了。

1385A. Three Pairwise Maximums

题意:给你三个整数x、y、z,然后需要找出三个数a、b、c,使这三个数满足 x=max(a,b)x=max(a,b), y=max(a,c)y=max(a,c) and z=max(b,c)z=max(b,c),或者确定这三个数不存在

思路:最大的两个数必须相同

#include<bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--) {
		vector<int> v(3);
		cin >> v[0] >> v[1] >> v[2]
			;
		sort(v.begin(), v.end());
		if (v[1] == v[2]) {
			cout << "YES" << endl;
			cout << 1 << ' ' << v[0] << ' ' << v[2] << endl;
		}
		else {
			cout << "NO" << endl;
		}
	}
	return 0;
}

1385B. Restore the Permutation by Merger

题意:给你一个由1-n的排列,然后两个相同的配列进行合并。例如:排列p:[3,1,2],则两个排列合并的可能情况有[3,1,2,3,1,2]、[3,3,1,1,2,2]、[3,1,3,1,2,2],要你还原出原本的排列。

思路:每次找出第一次出现的数即可,因为在一个排列中,每个数只可能出现一次。合并前后顺序不会改变。

#include<bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--) {
		int n;
		cin >> n;
		vector<int> v(n * 2);
		int i;
		for (i = 0; i < 2 * n; i++) {
			cin >> v[i];
		}
		unordered_map<int, int> mmid;
		vector<int> v1, v2;
		for (i = 0; i < 2*n; i++) {
			if (mmid[v[i]]==0) {
				v1.push_back(v[i]);
				mmid[v[i]] = 1;
			}
			else {
				v2.push_back(v[i]);
			}
		}
		for (i = 0; i < n; i++) {
			cout << v1[i] << ' ';
		}
		cout << endl;
	}
	return 0;
}

1385C. Make It Good

题意:如果能通过以下操作,从数组b中获得一个非递减的数组c,则成数组b为好。选择b的第一个或最后一个元素,将其从b中删除,并将其附加到数组c的末尾。

题面给定一个数组a,要你删除前k个元素,是它满足好数组的定义。(k可以为0).

思路:其实仔细观察以下题面给的样例,只要数组满足中间大两边小即可。

#include<bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--) {
		int n;
		cin >> n;
		vector<int> v(n);
		int i;
		for (i = 0; i < n; i++) {
			cin >> v[i];
		}
 
		i = n - 1;
		while (i > 0 && v[i] <= v[i - 1]) {
			i--;
		}
 
		while (i > 0 && v[i] >= v[i - 1]) {
			i--;
		}
		int ans = i;
		cout << ans << endl;
 
	}
	return 0;
}

1385D. a-Good String

题意:这是一个递归定义。定义字符串串为 c-good需要满足以下三个条件

  • 若字符串长度为1,则s1=c。
  • 若字符串长度大于1,前半部分s1=s2=s2=sn/2=c 并且后半部分 是(sn/2+1sn/2+2……sn) 是**(c+1)-good**
  • 若字符串长度大于1,后半部分s1=s2=s2=sn/2=c 并且前半部分 是(sn/2+1sn/2+2……sn) 是**(c+1)-good**

给你一个字符串,要你判断需要改动字符串多少次,才能够满足上述定义**‘a’-good**

思路:这题就是暴力找了。每次递归查找一半字符串。因为字符串长度为n,所以每次二分递归下去,最多递归Log(n)次,,加上每次判断需要改动字符数量为n,所以整体复杂度为nlogn。

#include<bits/stdc++.h>
using namespace std;
 
int check(string str,char ch) {
	int i;
	int cnt = 0;
	for (i = 0; i < str.size(); i++) {
		if (str[i] != ch)
			cnt++;
	}
	return cnt;
}
int ans = 0;
int solve(string str, char ch,int res) {
	if (str.size() == 1) {
		if (str[0] != ch) {
			return res + 1;
		}
		return res;
	}
	int len = str.size();
	string str1 = str.substr(0, len / 2);
	string str2 = str.substr(len / 2);
	int cnt1 =check (str1, ch);
	int cnt2 = check(str2, ch);
 
	return min(res+solve(str2, ch + 1,res) + cnt1, res+solve(str1, ch + 1,res) + cnt2);
}
 
int main() {
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--) {
		int n;
		ans = 0;
		cin >> n;
		string str;
		cin >> str;
		ans=solve(str, 'a',0);
		cout << ans << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43058685/article/details/107421701