牛客周赛 Round 123_C_小红出对 (哈希表+哈希集合)

牛客周赛 Round 123_C_小红出对

题目描述:

小红定义一个「对」为两张牌面数字相同的牌。

小红有 n 张牌,她每次能打出一个「对」,但为了不让小紫发现她作弊,在所有打出的牌中不能有两张花色与牌面数字都相同的牌。

小红想知道,她最多可以打出多少张牌,请你帮他找出一种出牌方案。
原题连接

题解:

解题思路:

思路一(哈希表+哈希集合):

1、

  • 不能出现两张完全相同的牌 (数字+花色),所以对每种 (a, 花色) 只保留一张(想到集合)。
  • 按数字 a 分组,统计这个数字下有多少种不同花色的牌(想到哈希表)。
  • 每两张牌可以组成一个「对」,从同一个 a 的哈希表里两两配对即可,求总共能出的牌数和具体配对方案。

set<pair<数字,花色>> used;
unordered_map<数字, vector<下标> >mp;

代码实现

代码实现(思路一(哈希表+哈希集合)):
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    // used 记录已经出现过的 (牌面数字 a, 花色 c)
    // 如果同一个 (a, c) 在输入中出现多次,只能选其中一张
    set<pair<int,char>> used;

    // mp[a] 存储:牌面数字为 a 的、且花色各不相同的牌的下标集合
    // 例如 a=1,可能对应下标 {1, 3, 7},表示 1A,1B,1C 三张牌
    unordered_map<int, vector<int>> mp;

    // 读入每一张牌
    for (int i = 1; i <= n; ++i) {
        int a;   // 牌面数字
        char c;  // 花色 A/B/C/D
        cin >> a >> c;

        pair<int,char> key = {a, c}; // 一个具体的牌型 (a, 花色)

        // 如果这个 (a, 花色) 之前没有出现过,就保留这张牌的下标
        if (!used.count(key)) {
            used.insert(key);   // 标记这个 (a, 花色) 已经用过
            mp[a].push_back(i); // 把这张牌的下标放入牌面为 a 的桶中
        }
        // 如果已经出现过,则跳过,不再加入,保证不会选到两张完全相同的牌
    }

    // 保存所有要打出的「对」:每个 pair<int,int> 是一对牌的两个下标
    vector<pair<int,int>> ans;

    // 遍历每一种牌面数字 a 对应的桶
    for (auto &kv : mp) {
        auto &v = kv.second; // 这个牌面数字 a 下,不同花色的所有牌的下标
        if (v.size() < 2) continue; // 少于两张牌,无法组成任何一个「对」

        // 为了输出更有序(非必须),先按下标排序
        sort(v.begin(), v.end());

        // 按顺序两两配对:(v[0], v[1])、(v[2], v[3])、...
        for (size_t i = 1; i < v.size(); i += 2) {
            ans.emplace_back(v[i-1], v[i]);
        }
    }

    // 输出总共打出的牌数 = 对数 * 2
    cout << ans.size() * 2 << "\n";

    // 输出每一对牌的下标
    for (auto &p : ans) {
        cout << p.first << " " << p.second << "\n";
    }

    return 0;
}

牛客周赛 Round 123_C_小红出对_原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
A星空1236 小时前
一、Linux嵌入式的I2C驱动开发
linux·c++·驱动开发·i2c
凡人叶枫7 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
会叫的恐龙7 小时前
C++ 核心知识点汇总(第六日)(字符串)
c++·算法·字符串
小糯米6017 小时前
C++顺序表和vector
开发语言·c++·算法
独望漫天星辰7 小时前
C++ 多态深度解析:从语法规则到底层实现(附实战验证代码)
开发语言·c++
王老师青少年编程8 小时前
2024年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第3题)
c++·题解·真题·csp·信奥赛·csp-s·提高组
凡人叶枫8 小时前
C++中输入、输出和文件操作详解(Linux实战版)| 从基础到项目落地,避坑指南
linux·服务器·c语言·开发语言·c++
CSDN_RTKLIB8 小时前
使用三方库头文件未使用导出符号情景
c++
rainbow688910 小时前
Linux文件描述符与重定向原理
c++
CodeSheep程序羊11 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展