本期周赛几乎忘记参加,在最后几分钟的时候上来看了看。那些选择判断一通乱选,填空题也已经被吐槽得差不多了,这里不多说,只说我对第一道编程题的看法(吐槽)。因为 C 站的机制是,即使它错了,它也不会承认(印象里只承认且改过一次),再争辩只会把你拉黑,甚至限流也有可能,所以只能把我的观点放在博客里,不再专门去反馈了。


先来看题目:

给定一组n个正整数,要求每次选其中一个数乘以或除以一个素数(称为一次凑数),问至少需要凑数多少次可以把所有的数都凑成相等。

输入描述:

第一行输入n个正整数(0<n<=1000000,其中每个数都小于1000000)。

输出描述:

可以把所有的数都凑成相等需要至少进行的凑数次数t(t>=0)。

输入样例:

5 20

输出样例:

2

我的观点是:这是道好题——好题在我这里的定义是,大部分人的解读是错的。而且至少目前来看,还没发现有人说对了。甚至我有九成的把握,此题测试用例的“标准答案”也是错的,剩下一成留给出题人来“深度解读”题意。

我认为此题关于“凑数”的定义是没有歧义的:

  1. 每次选其中一个数
  2. 将其乘以除以一个素数(质数)

同时满足上面两点即称为“一次凑数”。而将所有数字通过凑数变成相等的目标数字,却是没有规定的。

所以根据上述规则,对于给出的样例的两个数字 5 和 20 来说,有三种最优的方式(两次凑数)将其变成相等。

  •  , 

只有两个数字时,找出这样的目标数字并不难——肉眼可见,前两种方法分别是最小公倍数最大公约数。但能不能把这种规律扩展到三个数字以上呢?相信很多人的第一反应也是这样做的(通过测试用例的答案来看,感觉出题人可能也是这样想的)。但是很遗憾,由于“凑数”的定义是“其中一个数“”可以“乘以或除以”,并没有规定所有数都只能乘以或除以,所以存在第三种情况,即当某一部分的数字乘以一个素数,另一部分的数字除以一个素数的时候,也就是说,将所有数字变成一个最小公倍数和最大公约数之间的中间数字的时候,总的操作数更少。

举个简单的例子:2, 4, 8 。这三个数字的最小公倍数是 8, 最大公约数是 2,但是如果将三个数字都变成 8 或 2,都需要 3 次凑数:

但是如果把三个数字都变成 4,只需要 2 次凑数:

所以,我们不能完全通过找最小公倍数或最大公约数,找到最优的凑数方案。

那该怎么做呢?

我们知道,任何正整数都可以进行质因数分解,写成  的形式。其中  表示所有素数, 。

而将所有整数都变成一个相等的目标数字,等价于将所有整数的质因数排列形式变成一致。其中,整数里原本没有的质数,就要加上(乘以),原本多出来的质数,就要减少(除以),最终使得所有数字包含的每个质数的个数都各自相同。而相信你也看出来了,这里的“加上”和“减少”操作,其实就是本题所定义的“凑数”。

用公式来说明,假如有三个整数 ,分别可以写成:

而我们想要凑成的最终数字,应该是:

其中, 各自通过加减,统统变成  各自通过加减,统统变成  各自通过加减,统统变成  。不难看出,本题所要找的“凑数次数”,就是上面这些质数原本的个数变成最终个数,所需要的加或减的次数之和。而要使这个“次数之和”最小,每个质数原本的个数到最终个数的距离之和就必须最小。

所以,问题的关键变成了如何找出每个质数的“最终个数”。

相信有点数学基础的同学,很容易就能发现:在一群数中间找到一个数,使得所有数字到这个数字的距离之和最小,那么这个数必然是这群数字的中位数。——实际上,这也是中位数用处最广的特性之一。

到此,解题方法呼之欲出了。只需下面三步:

  1. 将所有整数进行质因数分解,找出所有质数的个数
  2. 将这些质数的个数分别进行排序,找到每个质数个数的中位数(没有该质数的整数相应的个数记为 0,参与排序)
  3. 累加每个质数到其中位数的个数之差。

相关代码放在某个地方了,这里就不重复了 :D

但是很遗憾,虽然我自信这种做法是正确的,但却通不过 C 站的测试。——这也是为什么我说九成认定 C 站的答案错了。

以彼之矛攻彼之盾,下面我们用 C 站本题自己的用例来证明它是错的。

本题有一组相对数量较少的用例如下:

标准答案是 38。也就是说 C 站认为需要至少 38 次凑数才能将所有数字变成相等。

虽然我不知道 C 站认为的最终相等的数字是多少,但我知道将所有数字都变成 1,是需要 38 次的,所以可以拿来进行分析和比较。具体如下:

虽然本例有点变态(出现了6位质数),但万变不离其宗,用我们前面介绍的方法进行分析,步骤如下:

1、将所有整数进行质因数分解,用  形式表示:

2、将所有出现过的质数的个数单独进行排序,不足整数个数的用 0 补齐(说明某些整数自己没有这个质数),并找出中位数(由于本例整数个数为10,偶数,所以中位数可以取左边,也可以取右边,这里便于计算,统一取左边):

  • ,中位数为 1
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0
  • ,中位数为 0

可以看出,绝大多数质数在所有整数中出现的个数都是1,所以本例的数字大概率是随机生成,并不是一个好的示例,但判断的逻辑是一样的。这一步也提示了最优的目标数字是 2(只有 2 的个数中位数是1,其余质数个数中位数都是 0)。

3、将每个质数个数列表中的其他数字向其中位数“靠齐”。以 2 和 3 为例:

  • ,所有数字变成 1,需要进行 7 次凑数——两个 0 变成两个 1需要加上两个1;2、3、3变成3个1,需要分别减去1、2、2
  • ,所有数字变成 0,需要进行 4 次凑数——1、1、2全变成 0需要分别减去1、1、2

其余质数依次类推。最后再将所有次数累加,得到较之“标准答案”更优的答案——32。所以,我认为的正确答案应该是 32,也就是将所有数字变成 2,仅需要 32 次凑数:

其实,通过肉眼就可以发现,十个整数中有八个偶数,只有两个奇数,很显然将两个奇数乘以 2,要比将八个偶数除以 2,次数更少。


至于如何通过 C 站本题的测试,我也早已有了答案,只是对于这种题意和答案不符的情况,还是不吐(槽)不快。

好了,是非对错,有缘读到这里的读者自己判断吧。

也欢迎有人提出反对意见,毕竟胜负终归浮云,唯有真理越辩越明。

小议CSDN周赛57期 - 凑数相关推荐

  1. CSDN 周赛37期题解

    CSDN 周赛37期题解 1.题目名称:幼稚班作业 2.题目名称:异或和 3.题目名称:大整数替换数位 4.题目名称:莫名其妙的键盘 卡个bug 小结 1.题目名称:幼稚班作业 幼稚园终于又有新的作业 ...

  2. CSDN周赛56期 - 八阿哥依旧

    之前54期被判作弊,申述无果,反被客服拉黑(水平不够,脾气够够的),让我彻底死心,从此粉转路.各种平台也不止C站一家,确实没有必要一棵树上吊shi.各位如果真心想通过竞赛提高自己的话,实在没必要来C站 ...

  3. CSDN周赛52期及53期浅析

    好久没写题解了,没办法,C站的题目更新的速度太慢了,重复考过去的老题已经不能再进步了.52期还混了个名次,总要写篇文章完成一下任务.而53期就惨了去了,三道选择题全蒙错了. 反正我个人觉得在现在C站的 ...

  4. < CSDN周赛解析:第 27 期 >

    CSDN周赛解析:第 27 期

  5. CSDN周赛第30期题目解析(天然气定单、小艺读书、买苹果、圆桌)

    CSDN周赛第30期,我应试成绩"0"分.试着对天然气定单.小艺读书.买苹果

  6. 《痞子衡嵌入式半月刊》 第 57 期

    痞子衡嵌入式半月刊: 第 57 期 这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期. 本期刊是开源项目(GitHub: JayHeng/pz ...

  7. 网课助手浏览器版怎么更新_MIUI版本更新动态:跨屏协作来袭(第57期)

    MIUI版本更新动态分享第57期 Tips:本周部分机型的内测开发版迎来新功能跨屏协作更新适配,使用上依据不同的网络环境延迟略有差异,功能上支持文件拖拽,多窗口操作,电脑编辑手机文件,使用上功耗上还有 ...

  8. CSDN 第六期编程竞赛做题记录

    CSDN 第六期编程竞赛做题记录 -- CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/16 9.18周日闲来无视写一下 csdn 的编程题,每期编程 ...

  9. 黑马57期视频免费下载

    黑马视频一直都是经典,教学水平也是首屈一指,对各初学者进入互联网行业起到了很大的帮助,由于黑马培训实在很好,这里免费给他们打个广告,就不收他广告费了,哈哈.不过每个培训机构都要接近2万的培训费用,对于 ...

最新文章

  1. 魔豆路由工程版体验:智能路由脱离手机的尝试
  2. 6.10 docker(三) 终止
  3. 使用python用什么软件-python开发工具有哪些(初学python用什么软件)
  4. 华为配置(S3100)
  5. weblogic内存溢出linux,解决weblogic内存溢出有关问题
  6. [Leedcode][JAVA][第990题][等式方程的可满足性][并查集]
  7. python怎么写微分方程_python微分方程
  8. python 网络编程_python网络编程示例(客户端与服务端)
  9. 顺序堆栈实现学生信息管理系统
  10. atitit.自己动手开发编译器and解释器(2) ------语法分析,语义分析,代码生成--attilax总结
  11. 美工建模-PR视频剪辑自学教程
  12. jdk10和jdk8共存和快速切换
  13. Day001-2021-07-29 变量定义/数据类型/基础运算 判断/循环/数组
  14. Java不同字符使用下划线分隔_004_Java语言基础(a-变量)
  15. Yolo opencv刻度尺识别 刻度读数识别 水尺识别 水位识别源码
  16. 每日一题(二三)function Foo(){ Foo.a = function(){console.log(1); } this.a = function(){console.log(2)}) Fo
  17. 用c#做的打地鼠小游戏,整理一下上课学的
  18. Datatable 列名
  19. 如何免费获得15G的 Google Drive 账号
  20. 足球和oracle列(4):巴西惨败于德国,认为,差额RAC拓扑控制!

热门文章

  1. 高考不分文理了!8省市高考综合改革方案“出炉”!
  2. 双11,美的、格力们又盯上了厨房小家电
  3. Byobu 使用技巧
  4. 超简单但又超有效的基于CNN的暗光成像模型
  5. (docker 容器)服务器搭建selenium-grid平台并构建jenkins job全过程
  6. mysql官网下载linux版本
  7. Windows7系统安装与升级
  8. 利用Arduino Mega的Analog端口无法驱动L298N电机芯片的解释
  9. 浮点运算计算机在线,浮点运算
  10. 程序员创业的情怀和梦想