尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

CCUT应用OJ题解——贪吃的松鼠

CCUT应用OJ题解——贪吃的松鼠
📅 发布时间:2026/6/19 10:40:39

题目简介

  • 来源:1033 贪吃的松鼠 - CCUT应用OJ
  • 题意:给定长度为 \((n-1)\times m+k\) 的序列,其中 \(n-1\) 个数出现 \(m\) 次,有且仅有 1 个数字出现 \(k\) 次,输出这个出现 \(k\) 次的数字。其中序列值域上界为 \(2^{30}\)。
  • 数据范围:\(n\le 10^5,1<m\le 9,k<m\);时空限制:3s/256M
  • 本题照搬自Leetcode 137. 只出现一次的数字 II。
  • 注:若无特殊说明,博主的代码模板如下。博主通过定义solve函数处理多组测试用例。博主在后文之战时solve函数。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define ln '\n'
#define fi first
#define se secondint main() {ios::sync_with_stdio(0),cin.tie(0);while(cin>>...){//此处即为处理多组测试用例,...换为实际输入变量solve();}return 0;
}

题解

朴素想法

一个朴素的想法如下:定义权值数组 \(cnt[i]\),用于统计 \(i\) 的出现次数。但由于值域上界高达\(2^{30}\),以 \(\texttt{int}\) 型数组为例,需约 \(4\text{GB}\) 内存,因此无法开下这么大的数组。此想法不可行。

解法1:哈希表

如果你学过 C++,那么则可使用 unordered_map一发AC。

void solve(){unordered_map<int, int> cnt;int id;for (i64 i = 0; i < 1LL * m * (n - 1) + k; i++) {cin >> id;cnt[id]++;}for (auto i : cnt) {if (i.se != m) {cout << i.fi << ln;break;}}
}

解法2:二进制优化

  • 核心思想:若除了一个数以外,其余数都出现了相同次数(设 \(m\) 次),则可通过统计二进制每一位上 \(1\) 的出现次数,并对 \(m\) 取模,从而得到那个特殊数。
  • 数学证明:
    • 考察整数\(x_i\),将其按二进制进行位权展开(由于题中值域上界为\(2^{30}\),故\(31\)位足够表示):\(x_i = \sum_{j=0}^{30} b_{i,j} \cdot 2^j, \quad b_{i,j} \in \set{0,1}\)
    • 统计每一位上 \(1\) 出现的次数:\(A_j = \sum_{i=1}^{m(n-1)+k} b_{i,j}\),其可被拆为两部分:\(A_j = \underbrace{\sum_{x \in S_m} m \cdot b_{x,j}}_{\text{出现 m 次的数贡献}} + \underbrace{k \cdot b*{x^*,j}}_{\text{出现 k 次的异常数贡献}}\)
    • 模运算具有如下性质:\((a + b) \bmod m = ((a \bmod m) + (b \bmod m)) \bmod m\),因此通过取模即可将异常数的贡献保留。
    • 对每一位计数 \(A_j \bmod m\):\(A_j \bmod m = \Big(\sum_{x \in S_m} m \cdot b_{x,j} + k \cdot b_{x^*,j}\Big) \bmod m\),并且 \(m \cdot b_{x,j} \equiv 0 \ (\text{mod } m)\) 对任何 \(b_{x,j} \in {0,1}\) 都成立。故得:\(A_j \bmod m = (k \cdot b_{x^*,j}) \bmod m\)
    • 由于题目给出 \(k < m\),故:

\[k \cdot b_{x^*,j} \bmod m = \begin{cases} 0, & b_{x^*,j} = 0 \\ k, & b_{x^*,j} = 1 \end{cases} \]

得证。

也就是说,模运算把“其他所有出现 m 次的数”完全消掉,只剩下那个出现 k 次的数的二进制痕迹。将其转换为十进制,即为最终答案。

void solve(){int a[35]={0};for(int i = 0;i < m * (n-1) + k ; i++){int num;scanf("%d",&num);for(int j = 0; j < 31; j++){if(num & (1 << j)) a[j] ++; // 循环左移,统计二进制中每一位上1的出现情况a[j] %= m;// 边统计边取模,防止爆了}}int ans = 0;for(int j = 0;j < 31;++j)if(a[j] != 0) ans += pow(2,j); // 还原出异常值即可printf("%d\n",ans);
}

相关新闻

  • Java流程控制——Scanner进阶使用
  • 结对编程心得
  • 关于结对编程的一些感悟

最新新闻

  • 深入解析MC68HC908AZ32A指令集与SIM模块:从Opcode到系统协调
  • 从3天到10分钟:OpCore-Simplify如何让黑苹果配置变得简单高效
  • 2026寄大件怎么便宜?个人快递折扣渠道实测对比 - 快递物流资讯
  • Bili.UWP终极指南:Windows 11上最高效的B站客户端使用方案
  • 四款新开源图像生成模型硬核实测与选型指南
  • SAP PS 项目状态与字段选择:从权限控制到流程优化的实战配置

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号