[ARC121B] RGB Matching 题解

题意

  • \(2N\) 个物品,每个物品有可爱度 \(a_i\) 和颜色 \(c_i\),将其两两配对。假设物体 \(i\)\(j\) 配对,则 \(c_i\neq c_j\),则会增加 \(|a_i-a_j|\) 的不满意度,求最小的不满意度。

分析

  • 这道题可以贪心解决。我们尽量让每一对物品颜色相同,令每种颜色的总个数为 \(cnt_c\),则:
  1. \(cnt_R\)\(cnt_G\)\(cnt_B\) 均为偶数,则答案为 \(0\)
  2. \(cnt_R\)\(cnt_G\) 为奇数(其余情况同理),那么我们将颜色为 R 和 G 的物品个留出一个配对,剩余的物品以相同颜色两两配对;也可以将一个 R 和一个 B 配对,再把一个 G 和一个 B 配对。取这两种情况的最小值即可。
  • 时间复杂度 \(O(n\log n)\)

AC 代码

#include <bits/stdc++.h>
#define int long long
#define inf 1e18
#define N 200005
using namespace std;
int n;
vector<int> a[4];

inline int read(int &x) {
	char ch = x = 0;
	while (ch < '0' || ch > '9')
		ch = getchar();
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + ch - 48;
		ch = getchar();
	}
	return x;
}

inline int calc(int u, int v) {
	int ans = inf;
	if (a[v].empty()) {
		return ans;
	}
	int lu = a[u].size(), lv = a[v].size(), j = 0;
	for (int i = 0; i < lu; i++) { //求取差值最小的那一对
		while (j + 1 < lv && a[v][j + 1] <= a[u][i]) { //尺取法
			j++;
		}
		ans = min(ans, abs(a[u][i] - a[v][j]));
		if (j + 1 < lv) {
			ans = min(ans, abs(a[u][i] - a[v][j + 1]));
		}
	}
	return ans;
}

signed main() {
	read(n);
	n <<= 1;
	char ch = 0;
	int x;
	for (int i = 1; i <= n; i++) {
		read(x);
		ch = getchar();
		while (ch < 'A' || ch > 'Z') ch = getchar();
		if (ch == 'R') a[1].push_back(x);
		else if (ch == 'G') a[2].push_back(x);
		else a[3].push_back(x);
	}
	vector<int> res;
	for (int i = 1; i <= 3; i++) {
		sort(a[i].begin(), a[i].end());
		if (a[i].size() % 2 == 1) {
			res.push_back(i);
		}
	}
	if (res.empty()) {
		printf("0");
		return 0;
	}
	int u = res[0], v = res[1], w = 6 - u - v;
	int uv = calc(u, v);
	int uw = calc(u, w);
	int vw = calc(v, w);
	printf("%lld", min(uv, uw + vw));
	return 0;
}
  • 感谢观看!留个赞吧~
posted @ 2024-02-27 19:48  wswwhcs  阅读(3)  评论(0编辑  收藏  举报