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

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

题目简介

  • 来源:1033 贪吃的松鼠 - CCUT应用OJ,魔改自 Leetcode 137. 只出现一次的数字 II。
  • 题意:给定长度为 (n−1)×m+k(n-1)\times m+k(n1)×m+k 的正整数序列,其中 n−1n-1n1 个数出现 mmm 次,有且仅有 1 个数出现 kkk 次,输出这个出现 kkk 次的数。
  • 数据范围:n≤105,1<m≤9,k<mn\le 10^5,1<m\le 9,k<mn105,1<m9,k<m,序列值域上界为 2302^{30}230;时空限制:3s/256M
  • 注:若无特殊说明,博主的代码模板如下。博主通过定义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]cnt[i]cnt[i],用于统计 iii 的出现次数,之后遍历 cntcntcnt 数组,找出出现 kkk 次的元素并输出即可。
但由于序列值域上界高达2302^{30}230,以 int\texttt{int}int 型数组为例,需约 4GB4\text{GB}4GB 内存,因此无法开下这么大的数组。此想法不可行。

解法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:二进制优化

  • 核心思想:若除了一个数以外,其余数都出现了相同次数(设 mmm 次),则可通过统计二进制每一位上 111 的出现次数,并对 mmm 取模,从而得到那个特殊数。
  • 数学证明:
    • 考察整数xix_ixi,将其按二进制进行位权展开(由于题中值域上界为2302^{30}230,故313131位足够表示):xi=∑j=030bi,j⋅2j,bi,j∈{0,1}x_i = \sum_{j=0}^{30} b_{i,j} \cdot 2^j, \quad b_{i,j} \in \set{0,1}xi=j=030bi,j2j,bi,j{0,1}
    • 统计每一位上 111 出现的次数:Aj=∑i=1m(n−1)+kbi,jA_j = \sum_{i=1}^{m(n-1)+k} b_{i,j}Aj=i=1m(n1)+kbi,j,其可被拆为两部分:Aj=∑x∈Smm⋅bx,j⏟出现 m 次的数贡献+k⋅bx∗,j⏟出现 k 次的异常数贡献A_j = \underbrace{\sum_{x \in S_m} m \cdot b_{x,j}}_{\text{出现 m 次的数贡献}} + \underbrace{k \cdot b_{x^*,j}}_{\text{出现 k 次的异常数贡献}}Aj=出现 m 次的数贡献xSmmbx,j+出现 k 次的异常数贡献kbx,j
    • 模运算具有如下性质:(a+b)modm=((amodm)+(bmodm))modm(a + b) \bmod m = ((a \bmod m) + (b \bmod m)) \bmod m(a+b)modm=((amodm)+(bmodm))modm,因此通过取模即可将异常数的贡献保留。
    • 对每一位计数 AjmodmA_j \bmod mAjmodmAjmodm=(∑x∈Smm⋅bx,j+k⋅bx∗,j)modmA_j \bmod m = \Big(\sum_{x \in S_m} m \cdot b_{x,j} + k \cdot b_{x^*,j}\Big) \bmod mAjmodm=(xSmmbx,j+kbx,j)modm,并且 m⋅bx,j≡0(mod m)m \cdot b_{x,j} \equiv 0 \ (\text{mod } m)mbx,j0 (mod m) 对任何 bx,j∈0,1b_{x,j} \in {0,1}bx,j0,1 都成立。故得:Ajmodm=(k⋅bx∗,j)modmA_j \bmod m = (k \cdot b_{x^*,j}) \bmod mAjmodm=(kbx,j)modm
    • 由于题目给出 k<mk < mk<m,故:
      k⋅bx∗,jmodm={0,bx∗,j=0k,bx∗,j=1k \cdot b_{x^*,j} \bmod m = \begin{cases} 0, & b_{x^*,j} = 0 \\ k, & b_{x^*,j} = 1 \end{cases} kbx,jmodm={0,k,bx,j=0bx,j=1
      得证。

也就是说,模运算把“其他所有出现 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);
}
http://www.dtcms.com/a/537342.html

相关文章:

  • [已解决]Python将COCO格式实例分割数据集转换为YOLO格式
  • CSS Backgrounds (背景)
  • Blender入门学习08 - 骨骼绑定
  • 家装设计网站开发企业做网站大概多少钱
  • TCP/UDP端口、IP协议号与路由协议 强行记忆点总结
  • (一)React面试()
  • 配置文件加载顺序与优先级规则
  • 数字化转型迫在眉睫,企业应该如何面对?
  • 做网站百度云网站登录不了
  • HF4054H-B 50V耐压 集成6.1V过压保护和1.3A过流保护 42V热拔插性能的500mA锂电池线性充电芯片
  • 网站可以做音频线吗网站如何安装源码
  • 小学校园文化建设网站网站打不开显示asp
  • 142.DDR报错bank32,33,34
  • Android性能优化深度解析与实际案例
  • 网站素材网站建设的目标和需求
  • 与您探讨电子元器件结构陶瓷(陶瓷基板)的分类及结构陶瓷的应用
  • 模板建站自适应互联网网站分了
  • 苹果ios安卓apk应用APP文件怎么修改手机APP显示的名称
  • 网站界面用什么做的网站创建方法
  • 《自动控制原理》第 3 章 线性控制系统的运动分析:3.6、3.7
  • 特征选择中的统计思维:哪些变量真的重要?
  • 项目七 使用ODL Yang UI操作流表
  • 电子商务网站怎么建料远若近网站建设
  • [CSP-S 2024] 超速检测
  • 基于MT5的K线处理逻辑
  • 河南郑州网站建设哪家公司好免费wordpress主题下载地址
  • 低空经济网络安全的政策体系构建
  • 网页设计网站规划深圳设计网站公司哪家好
  • 【Etcd 】Etcd 详解以及安装教程
  • 文交所网站建设方案饰品企业网站建设