CF1144D Equalize Them All

发布时间 2024-01-07 16:23:14作者: cloud_eve

第一次看的时候确实被题面吓了一跳,没有好好思考就放弃了。其实题目还是蛮简单的。

题意

对于两种操作,我们可以进行分类讨论。

\(a_i > a_j\)

操作一:将 \(a_i\) 变为了 \(2 \times a_i - a_j\)
操作二:将 \(a_i\) 变为了 \(a_j\)

\(a_i \le a_j\)

操作一:将 \(a_i\) 变为了 \(a_j\)
操作二:将 \(a_i\) 变为了 \(2 \times a_i - a_j\)

思路

观察上面的结果,我们可以发现不论 \(a_i\)\(a_j\) 的大小关系如何,我们都可以通过两种操作 直接\(a_i\) 变为 \(a_j\)

那么,为了将所有数字变为相同的,我们应该选择将所有数字转换为原数组中数量最多的数,所以这道题的做法其实就是找出这个数组的众数,再用 \(n\) 将其减去,即为答案。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 200005;
int n, cnt = 1, maxn = 0;
int mode, a[N], a2[N];
int main() {
//	freopen("equalize.in", "r", stdin);
//	freopen("equalize.out", "w", stdout);
	scanf("%d", &n);
	if (n == 1) {
		printf("0\n");
		return 0;
	}
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		a2[i] = a[i];
	}
	sort(a + 1, a + n + 1);
//	for (int i = 1; i <= n; i++) {
//		cout << a[i] << endl;
//	}
	for (int i = 1; i < n; i++) {
		if (a[i] == a[i + 1]) cnt++;
		else cnt = 1;
		if (cnt > maxn) {
			mode = a[i];
			maxn = cnt;
		}
	}
	printf("%d\n", n - maxn);
//	cout << mode << endl;
	if ((n - maxn) == 0) return 0;
	for (int i = 2; i <= n; i++) {
		if (a2[i - 1] == mode) {
			if (a2[i] > a2[i - 1]) printf("2 %d %d\n", i, i - 1);
			else if (a2[i] < a2[i - 1]) printf("1 %d %d\n", i, i - 1);
			a2[i] = a2[i - 1];
		}
	}
	for (int i = n - 1; i >= 1; i--) {
		if (a2[i + 1] == mode) {
			if (a2[i] > a2[i + 1]) printf("2 %d %d\n", i, i + 1);
			if (a2[i] < a2[i + 1]) printf("1 %d %d\n", i, i + 1);
			a2[i] = a2[i + 1];
		}
	}
	return 0;
}

//a[i] > a[j]
// 1: 2*a[i]-a[j]
// 2: a[j]
//a[i] < a[j]
// 1: a[j]
// 2: 2*a[i]-a[j]

注意:在求众数时循环条件为 i < n,所以需要特判 n == 1 的情况