题解:洛谷 P2902 Pearl Pairing

【题目来源】

洛谷:P2902 [USACO08MAR] Pearl Pairing G - 洛谷

【题目描述】

在 Bessie 最近的生日聚会上,她收到 \(N(2\le N \le 10^5,N\equiv0\pmod{2})\) 颗珍珠。一共有 \(C\) 种颜色的珍珠(\(1\le C \le N\)),第 \(i\) 种颜色的珍珠有 \(C_i\) 颗。

观察到珍珠的数量 \(N\) 总是偶数,她的创意来了,决定配对珍珠,使每对珍珠有两种不同的颜色。数据保证存在答案。请帮助 Bessie 执行这样的配对,如果有多种配对的方法,输出任意一种即可。

【输入】

\(1\) 行:两个空格分隔的整数:\(N\)\(C\)

\(2\ldots C+1\)行:第 \(i+1\) 为颜色 \(i\) 的珍珠数 \(C_i\)

【输出】

\(1\ldots \dfrac{N}{2}\) 行:第 \(i\) 行包含两个整数 \(a_i\)\(b_i\),表示 Bessie 可以将各自颜色为 \(a_i\)\(b_i\) 的两个珍珠配对。

【输入样例】

8 3
2
2
4

【输出样例】

1 3
1 3
2 3
3 2

【核心思想】

  1. 问题分析:给定 \(N\) 颗珍珠(\(N\) 为偶数),共 \(C\) 种颜色,第 \(i\) 种颜色有 \(C_i\) 颗。要求将珍珠两两配对,每对珍珠颜色不同。数据保证有解。这是一个贪心构造问题,关键在于发现将同色珍珠均匀分散后,按位置配对即可保证每对不同色。

  2. 算法选择

    • 均匀分散 + 位置配对:将每种颜色的珍珠按顺序放入数组,然后让第 \(i\) 颗与第 \(i + N/2\) 颗配对
    • 鸽巢原理保证:由于最多颜色的珍珠数不超过 \(N/2\)(否则无法配对),任何颜色在数组前半段和后半段都不会完全占据同一半,从而保证配对时颜色不同
  3. 关键步骤

    • 读取输入\(N, C\) 和每种颜色的数量 \(C_i\)
    • 构建数组:将 \(C_i\) 颗颜色为 \(i\) 的珍珠依次放入数组 \(a[1..N]\)
    • 配对输出\(i\)\(1\)\(N/2\)):
      • 输出 \(a[i]\)\(a[i + N/2]\) 作为一对
  4. 时间/空间复杂度

    • 时间复杂度:\(O(N)\),构建数组和输出配对各 \(O(N)\)
    • 空间复杂度:\(O(N)\),存储珍珠颜色数组
  5. 贪心配对的核心思想

    • 均匀分散策略:将同色珍珠连续放置,由于数量最多的颜色不超过 \(N/2\),该颜色最多占据前半段或后半段的一半,不会在同一配对位置出现同色
    • 对折配对:第 \(i\) 与第 \(i + N/2\) 配对,相当于将数组对折,两半中同一位置的珍珠配对。由于同色珍珠连续且长度 \(\le N/2\),对折后不会相遇
    • 存在性保证:题目保证有解,意味着 \(\max(C_i) \le N/2\),这是上述策略可行的充要条件
    • 适用于"均匀分组 + 避免同色相邻/配对"类问题,核心是利用鸽巢原理保证构造可行性

【算法标签】

普及 #贪心

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 100005 * 2;
int n, c, cur;  // n: 总人数, c: 班级数, cur: 当前数组指针
int a[N];  // 学生数组

int main()
{
    cin >> n >> c;  // 输入总人数和班级数
    for (int i = 1; i <= c; i++)  // 处理每个班级
    {
        int x;
        cin >> x;  // 输入班级i的人数
        for (int j = 1; j <= x; j++)  // 将班级i的学生加入数组
        {
            a[++cur] = i;  // 用班级编号标记学生
        }
    }

    // 输出配对结果
    for (int i = 1; i <= n / 2; i++)  // 配对n/2对
    {
        cout << a[i] << " " << a[i + n / 2] << endl;  // 输出一对学生
    }
    return 0;
}

【运行结果】

8 3
2
2
4
1 3
1 3
2 3
2 3
posted @ 2026-08-28 15:55  团爸讲算法  阅读(2)  评论(0)    收藏  举报