coding笔记: acwing 1296 聪明的燕姿
acwing 1296 聪明的燕姿
Description
城市中人们总是拿着号码牌,不停寻找,不断匹配,可是谁也不知道自己等的那个人是谁。
可是燕姿不一样,燕姿知道自己等的人是谁,因为燕姿数学学得好!
燕姿发现了一个神奇的算法:假设自己的号码牌上写着数字 S,那么自己等的人手上的号码牌数字的所有正约数之和必定等于 S。
所以燕姿总是拿着号码牌在地铁和人海找数字(喂!这样真的靠谱吗)。
可是她忙着唱《遇见》,想拜托你写一个程序能够快速地找到所有自己等的人。
Input
输入包含 k组数据。
对于每组数据,输入包含一个号码牌 S。
Output
对于每组数据,输出有两行。
第一行包含一个整数 m,表示有 m 个等的人。
第二行包含相应的 m个数,表示所有等的人的号码牌。
注意:你输出的号码牌必须按照升序排列。
Solution
求所有公约数之和
- 每个约数均不相同,且是选法数量之一。
$S = (p_1^0+p_1^1+…+p_1^{a1})(p_2^0+p_2^1+…+p_2^{a2})…*(p_k^0+p_k^1+…+p_k^{ak})$
1 | for(int j = 1+pri, t = pri; j<=x; t*=pri, j+=t){ |
- 上面的代码可以同时求出总和和每一项的值(等差数列求和)
- 避免使用pow函数(溢出风险+复杂度高)
- 终止条件: j>x
一种优化的判定质数的方法
初始版
1 | bool is_prime(int n){ |
利用已知信息+
1 | bool is_prime(int n){ |
只使用质数来判定
1 | bool is_prime(int n){ |
- 只有第三种才能AC,但感觉需要防止越界(i<cnt),但不加也可以AC
- 后两种方法都需要先预处理出质数
- 核心思想:我们可以发现n的所有约数都是成对出现的,即若d为n的约束,那么n/d也为n的约数。所以我们不需要枚举所有数,只需要枚举
的质数即可,也就是说d只需枚举到 即可
dfs遍历顺序
- 依次枚举p,a
- p(2,3,5,7,…)
- a(1,2,3,) // 在代码中未显示地枚举,而是用乘积代替,本质上是一个意思
- if(S mod j == 0)
- dfs(…)
优化(剪枝)
- 如果
,且pi比之前的质因子大的话(需要满足等式条件)直接可以将pi作为结果的因子 - 如果
,我们只需要遍历小于 的质因子即可(因为 )
code
1 |
|
- Post title:coding笔记: acwing 1296 聪明的燕姿
- Post author:sixwalter
- Create time:2023-08-05 11:14:26
- Post link:https://coelien.github.io/2023/08/05/coding-solution/acwing_1296/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments