当前位置: 首页 > news >正文

第三十天:世界杯队伍团结力问题

每日一道C++题:世界杯队伍团结力问题

一、问题描述

为出战世界杯需组建一支队伍,队伍团结力取决于队员性格基因。每个队员有一个性格基因(用字符串表示),其性格基因可通过循环改变排列方式。若队伍中最多有 x 个人的性格基因能完全相等,队伍团结力即为 x

已知有 n 个人可出战,每人有一个性格基因字符串,同时有 m 个信息,每个信息表示 a 想要和 b 一起出战。只有当 a 想和 b 出战且 b 也想和 a 出战时,两人才能一起出战,且这种出战意愿具有传递性。目标是计算派出队伍的最大团结力。

输入描述

  • 本题包含多组数据,第一行输入两个数字 nm,分别表示一共有 n 个人,以及 m 个出战信息 。
  • 接下来 n 行,每行输入一个字符串,表示每个人的性格基因。
  • 再接下来 m 行,每行两个编号 xy,表示 x 想要和 y 出战。

数据范围

  • 5 <= n <= 100000
  • 1 <= m <= 100000
  • 1 <= x, y <= n
  • 每个数据的字符串长度和不超过 100000

输出描述

每组数据输出一行,表示最大团结力。

二、解题思路与代码实现

解题思路

  1. 循环字符串判断:编写函数判断两个字符串通过循环是否能相等,这是判断队员性格基因是否可达成一致的基础。
  2. 并查集处理出战关系:利用并查集数据结构来处理队员之间的出战关系,将相互想出战的队员合并到同一个集合中,通过出战意愿的传递性构建出战小组。
  3. 统计团结力:对于每个出战小组,统计组内通过循环能达成一致的性格基因的最大数量,即为该小组的团结力,最终所有小组团结力的最大值就是整个队伍的最大团结力。

代码实现(C++)

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>using namespace std;// 检查两个字符串通过循环是否能相等
bool canBeEqual(const string& s1, const string& s2) {if (s1.length() != s2.length()) return false;string doubleS1 = s1 + s1;return doubleS1.find(s2) != string::npos;
}// 并查集数据结构
class UnionFind {
private:vector<int> parent;vector<int> rank;
public:UnionFind(int n) {parent.resize(n);rank.resize(n, 0);for (int i = 0; i < n; ++i) {parent[i] = i;}}int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]);}return parent[x];}void unionSet(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {if (rank[rootX] > rank[rootY]) {parent[rootY] = rootX;} else if (rank[rootX] < rank[rootY]) {parent[rootX] = rootY;} else {parent[rootY] = rootX;rank[rootX]++;}}}
};int main() {int n, m;while (cin >> n >> m) {vector<string> genes(n);for (int i = 0; i < n; ++i) {cin >> genes[i];}UnionFind uf(n);for (int i = 0; i < m; ++i) {int x, y;cin >> x >> y;uf.unionSet(x - 1, y - 1);}unordered_map<int, unordered_map<string, int>> groupGenes;for (int i = 0; i < n; ++i) {int group = uf.find(i);for (int j = 0; j < genes[i].length(); ++j) {string rotated = genes[i].substr(j) + genes[i].substr(0, j);groupGenes[group][rotated]++;}}int maxSolidarity = 0;for (const auto& group : groupGenes) {int groupMax = 0;for (const auto& geneCount : group.second) {groupMax = max(groupMax, geneCount.second);}maxSolidarity = max(maxSolidarity, groupMax);}cout << maxSolidarity << endl;}return 0;
}

代码详细解释

  1. 函数 canBeEqual
    • 首先判断两个字符串长度是否相同,若不同则直接返回 false
    • s1 拼接自身得到 doubleS1,这样 doubleS1 涵盖了 s1 所有可能的循环排列。然后通过 find 函数检查 s2 是否为 doubleS1 的子串,若是则返回 true,表明两个字符串通过循环可相等,否则返回 false
  2. 并查集类 UnionFind
    • 初始化:构造函数为 parentrank 数组分配内存。parent 数组用于记录每个元素的父节点,初始时每个元素的父节点设为自身;rank 数组记录每个元素所在树的秩,初始值为 0,用于优化合并操作。
    • 查找操作 find:通过递归查找元素的根节点,并在查找过程中进行路径压缩,即将查找路径上的节点直接连接到根节点,以提高后续查找效率。
    • 合并操作 unionSet:找到两个元素的根节点 rootXrootY,若不同,则依据秩的大小进行合并。秩大的树作为合并后的根节点,秩相等时任选一个作为根节点并将其秩加 1
  3. main 函数
    • 输入处理:通过 while (cin >> n >> m) 处理多组输入数据,读取每组的人数 n 和出战信息数 m。接着读取 n 个性格基因字符串存入 genes 向量。
    • 并查集构建出战小组:创建 UnionFind 对象 uf,根据输入的出战信息,使用 uf.unionSet(x - 1, y - 1) 将相互想出战的队员合并到同一集合(注意编号需从 1 转换为 0 开始的数组索引)。
    • 统计每个出战小组内性格基因的循环排列数量:使用嵌套的 unordered_map groupGenes 来统计每个出战小组内各种循环排列的性格基因的数量。外层 unordered_map 以出战小组标识(通过并查集的 find 操作获取)为键,内层 unordered_map 以性格基因的循环排列字符串为键,值为该循环排列的出现次数。对每个队员的性格基因生成所有可能的循环排列并更新 groupGenes
    • 计算最大团结力:遍历 groupGenes,对于每个出战小组,找出组内出现次数最多的循环排列性格基因的数量 groupMax,所有小组的 groupMax 中的最大值即为整个队伍的最大团结力 maxSolidarity,最后输出 maxSolidarity
http://www.dtcms.com/a/354977.html

相关文章:

  • EF Core 编译模型 / 模型裁剪:冷启动与查询优化
  • QT之双缓冲 (QMutex/QWaitCondition)——读写分离
  • 企业如何管理跨多个系统的主数据?
  • MaxCompute MaxFrame | 分布式Python计算服务MaxFrame(完整操作版)
  • 【Lua】题目小练12
  • 如何实现HTML动态爱心表白效果?
  • 多版本并发控制MVCC
  • 黑马点评|项目日记(day02)
  • C#和Lua相互访问
  • 基于金庸武侠小说人物关系设计的完整 SQL 语句,包括数据库创建、表结构定义和示例数据插入
  • Docker 详解+示例
  • map底层的数据结构是什么,为什么不用AVL树
  • 机器学习回顾(一)
  • 陪诊小程序系统开发:搭建医患之间的温暖桥梁
  • Scrapy 基础介绍
  • 安全运维——系统上线前安全检测:漏洞扫描、系统基线与应用基线的全面解析
  • lwIP MQTT 心跳 Bug 分析与修复
  • 边缘计算(Edge Computing)+ AI:未来智能世界的核心引擎
  • HarmonyOS 组件与页面生命周期:全面解析与实践
  • Paimon——官网阅读:Flink 引擎
  • 【秋招笔试】2025.08.27华为秋招研发岗真题
  • 【新启航】3D 逆向抄数效率提升:自动化拼接工具与智能建模能力如何缩短 50% 项目周期
  • 聚类准确率计算——标签映射(Kuhn-Munkres匈牙利算法)问题的解决(详细并附完整代码)
  • 大模型RAG(Retrieval-Augmented Generation)
  • Python日期计算完全指南:从上周五到任意日期的高效计算
  • Cubemx+Vscode安装与环境配置
  • 聚焦建筑能源革新!安科瑞 “光储直柔” 方案护航碳中和目标实现
  • 162.在 Vue 3 中使用 OpenLayers 解析 GeoJSON 并为每个 Feature 填充渐变色
  • 如何调试一个EVM合约:实战操作 + 常见报错说明
  • 2025年第五届电子信息工程与计算机科学国际会议(EIECS 2025)