Codeforces Global Round 14 D. Phoenix and Socks(贪心/好题)
To satisfy his love of matching socks, Phoenix has brought his n socks (n is even) to the sock store. Each of his socks has a color ci and is either a left sock or right sock.
Phoenix can pay one dollar to the sock store to either:
- recolor a sock to any color c′ (1≤c′≤n)
- turn a left sock into a right sock
- turn a right sock into a left sock
The sock store may perform each of these changes any number of times. Note that the color of a left sock doesn't change when it turns into a right sock, and vice versa.
A matching pair of socks is a left and right sock with the same color. What is the minimum cost for Phoenix to make n/2 matching pairs? Each sock must be included in exactly one matching pair.
Input
The input consists of multiple test cases. The first line contains an integer t (1≤t≤1000) — the number of test cases.
The first line of each test case contains three integers n, l, and r (2≤n≤2⋅10^5; n is even; 0≤l,r≤n;l+r=n) — the total number of socks, and the number of left and right socks, respectively.
The next line contains 𝑛n integers ci (1≤ci≤n) — the colors of the socks. The first l socks are left socks, while the next r socks are right socks.
It is guaranteed that the sum of n across all the test cases will not exceed 2⋅10^5.
Output
For each test case, print one integer — the minimum cost for Phoenix to make n/2 matching pairs. Each sock must be included in exactly one matching pair.
Example
input
Copy
4
6 3 3
1 2 3 2 2 2
6 2 4
1 1 2 2 2 2
6 5 1
6 5 4 3 2 1
4 0 4
4 4 4 3
output
Copy
2
3
5
3
不妨设l大于等于r。首先可以将l和r中颜色相同的凑成一对直接抵消掉,则剩下的l的颜色与r的颜色互不相同(但l中可能有多只同一个颜色的袜子,r同理)。然后考虑怎么给这些配对。如果l和r不相等,设d = l - r,容易知道d是偶数,则肯定有d / 2只左袜子要变成右袜子。一种可行的贪心策略是从l中找两只同样颜色的袜子,将其中一只变成右袜子(当然变完后也要消掉),这样不断处理,当d变为0或者没有两只及以上相同颜色的左袜子。此时若d不为0,则只能将l中的d只左袜子既变方向又变颜色(因为右袜子中和这些相同的颜色的袜子肯定在一开始就被消掉了),对答案贡献为2 * d。这时候l = r,剩下的左袜子右袜子数量相同颜色彼此不同,对答案的贡献为剩下的左/右袜子的数量。
//注意:代码模板中的代码将会被复制到任何新创建的文件中,编辑代码模板中的代码,让他帮你自动增加固定代码吧
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int n, l, r, a[200005], a1[200005],b[200005],b1[200005];
int main(){
int t;
cin >> t;
while(t--) {
cin >> n >> l >> r;
for(int i = 1; i <= n; i++) a1[i] = b1[i] = 0;
for(int i = 1; i <= l; i++) {
cin >> a[i];
a1[a[i]]++;//用桶计数
}
for(int i = 1; i <= r; i++) {
cin >> b[i];
b1[b[i]]++;
}
for(int i = 1; i <= n; i++) {
int tmp = min(a1[i], b1[i]);
a1[i] -= tmp;//抵销
b1[i] -= tmp;
}
int ans = 0;
if(l >= r) {
int d = l - r;
d /= 2;
for(int i = 1; i <= n; i++) {
while(a1[i] >= 2 && d) {//贪心
a1[i] -= 2;
d--;
ans++;
}
while(a1[i] && b1[i]) {
a1[i]--;
b1[i]--;
}
}
if(d) ans += d * 2;
for(int i = 1; i <= n; i++) {
ans += b1[i];//因为上一步的操作没有在a1体现,此时a1和b1中的和不一样,必须以b1为准
}
} else {
int d = r - l;
d /= 2;
for(int i = 1; i <= n; i++) {
while(b1[i] >= 2 && d) {
b1[i] -= 2;
d--;
ans++;
}
while(a1[i] && b1[i]) {
a1[i]--;
b1[i]--;
}
}
if(d) ans += d * 2;
for(int i = 1; i <= n; i++) ans += a1[i];
}
cout << ans << endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-05-03 POJ1236 Network of Schools(强连通分量)
2020-05-03 P3387 【模板】缩点(Tarjan求强连通分量)