首页 > 其他分享 >Hankson的趣味题

Hankson的趣味题

时间:2023-01-21 13:11:47浏览次数:47  
标签:约数 10 正整数 int times 趣味 Hankson

Hankson的趣味题

Hanks 博士是 BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫 Hankson。

现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。

今天在课堂上,老师讲解了如何求两个正整数 $c_1$ 和 $c_2$ 的最大公约数和最小公倍数。

现在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:

已知正整数 $a_0,a_1,b_0,b_1$,设某未知正整数 $x$ 满足:

  • $x$ 和 $a_0$ 的最大公约数是 $a_1$;
  • $x$ 和 $b_0$ 的最小公倍数是 $b_1$。

Hankson 的“逆问题”就是求出满足条件的正整数 $x$。

但稍加思索之后,他发现这样的 $x$ 并不唯一,甚至可能不存在。

因此他转而开始考虑如何求解满足条件的 $x$ 的个数。

请你帮助他编程求解这个问题。

输入格式

输入第一行为一个正整数 $n$,表示有 $n$ 组输入数据。

接下来的 $n$ 行每行一组输入数据,为四个正整数 $a_0$,$a_1$,$b_0$,$b_1$,每两个整数之间用一个空格隔开。

输入数据保证 $a_0$ 能被 $a_1$ 整除,$b_1$ 能被 $b_0$ 整除。

输出格式

输出共 $n$ 行。

每组输入数据的输出结果占一行,为一个整数。

对于每组数据:若不存在这样的 $x$,请输出 $0$;

若存在这样的 $x$,请输出满足条件的 $x$ 的个数;

数据范围

$1 \leq n \leq 2000$,
$1 \leq a_0,a_1,b_0,b_1 \leq 2 \times {10}^9$

输入样例:

2
41 1 96 288
95 1 37 1776

输入样例:

6
2

 

解题思路

  因为$\text{lcm}(c, x) = d$,因此$x$是$d$的约数,因此想到可以通过枚举$d$的所有约数看看有多少个$x$同时满足给定的两个条件。在不超过$2 \times {10}^9$的数中,一个数最多有$1536$个约数,在不超过$2^{31}-1$的数中,一个数最多有$1600$个约数。求两个数的最大公约数的时间复杂度为$O(\log{x})$。因此可以推算出计算量大致为$2000 \times 1536 \times \log{x} \approx {10}^7$级别。

  实际上时间复杂度的瓶颈是分解$d$的约数,由于$d$最大可以取到$2 \times {10}^9$,因此$t$组数据共分解约数的计算量大致为$2000 \times \sqrt{2 \times {10}^9} \approx {10}^8$级别,而这题的时间限制为$0.3$秒,因此必然会超时。

  因此需要对分解约数这个瓶颈进行优化。分解约数的一般做法是从$1$一直枚举到$\sqrt{d}$,可以求出所有的约数。注意到约数可以通过质因子的组合来得到,现在把$d$看成质因子相乘的形式,枚举$1$一直枚举到$\sqrt{d}$中所有的质数,得到$d$的质因数分解形式,最后通过dfs来暴搜所有的约数。在$1 \sim \sqrt{2 \times {10}^9}$内的质数不到$5000$个,因此在分解质因数这里的计算量降到是${10}^7$级别,再加上暴搜所有约数判断条件,总共的时间复杂度大致是${10}^7$级别,可以过。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef pair<int, int> PII;
 5 
 6 const int N = 5e4 + 10;
 7 
 8 int a, b, c, d;
 9 int primes[N], cnt;
10 bool vis[N];
11 vector<PII> fs;
12 int ans;
13 
14 void get_prime(int n) {
15     for (int i = 2; i <= n; i++) {
16         if (!vis[i]) primes[cnt++] = i;
17         for (int j = 0; primes[j] <= n / i; j++) {
18             vis[primes[j] * i] = true;
19             if (i % primes[j] == 0) break;
20         }
21     }
22 }
23 
24 int gcd(int a, int b) {
25     return b ? gcd(b, a % b) : a;
26 }
27 
28 void dfs(int u, int x) {
29     if (u == fs.size()) {
30         if (gcd(a, x) == b && c / gcd(c, x) == d / x) ans++;    // 判断x是否满足题目条件
31         return;
32     }
33     for (int i = 0; i <= fs[u].second; i++) {
34         dfs(u + 1, x);
35         x *= fs[u].first;
36     }
37 }
38 
39 int main() {
40     get_prime(N - 1);   // 筛出sqrt(2*10^9)内的质数
41     int n;
42     scanf("%d", &n);
43     while (n--) {
44         scanf("%d %d %d %d", &a, &b, &c, &d);
45         int m = d;
46         fs.clear();
47         for (int i = 0; primes[i] <= m / primes[i]; i++) {  // 分解d的质因数
48             if (m % primes[i] == 0) {
49                 int s = 0;
50                 while (m % primes[i] == 0) {
51                     s++;
52                     m /= primes[i];
53                 }
54                 fs.push_back({primes[i], s});
55             }
56         }
57         if (m > 1) fs.push_back({m, 1});
58         ans = 0;
59         dfs(0, 1);  // 暴搜d的所有约数
60         printf("%d\n", ans);
61     }
62     
63     return 0;
64 }

 

参考资料

  AcWing 200. Hankson的趣味题(算法提高课):https://www.acwing.com/video/693/

标签:约数,10,正整数,int,times,趣味,Hankson
From: https://www.cnblogs.com/onlyblues/p/17063724.html

相关文章

  • 视频直播美颜sdk趣味功能的实现流程
    当下,随着直播、短视频等视频社交平台的进一步普及,大家已经逐渐无法离开这种新型的社交娱乐方式,其中一大部分原因是因为美颜sdk的加入,无论是强大的美颜功能,还是趣味拍摄方案,......
  • Python 中的迭代器趣味实践
    1.遍历文本文件中的单词假设存在文本文件test.txt,内容如下:TheZenofPythonBeautifulisbetterthanuglySimpleisbetterthancomplex注意文件包含有空行,要求完成如......
  • 大数据趣味学习探讨(一):学习框架的重要性
    文章目录​​学习框架的重要性​​​​一、痛点​​​​二、规则vs元规则​​​​三、无穷无尽的新问题​​​​四、感悟​​学习框架的重要性框架类似底层方法论,有人说学习......
  • 【C语言趣味教程】typedef 真爽不爽不要玩 | 初识结构体
    前言:本篇文章是一次大胆的尝试,我想试着改变我那枯燥不堪的文笔,试着能不能幽默风趣地讲解知识点。如果效果好的话,我会进一步尝试!希望大家喜欢! 学习结构体之前,我们先来讲讲 ......
  • 浩辰3D趣味排球建模,你学会了嘛?
    在3D设计师的日常工作中,经常需要面对复杂模型建模的挑战。相较于传统3D软件的命令复杂、不易操作,由浩辰CAD公司研发的浩辰3D提供了更强大的创意建模工具,以更为灵活、高效的......
  • ArkUI开发趣味体验,快来抽取限量HarmonyOS专属头像!
    本次ArkUI开发趣味体验活动,将手把手教大家如何在IDE里实操一个ArkUI程序,通过补充缺失代码,成功运行程序开启抽奖功能,抽取个人专属头像,做HarmonyOS第一批数字藏品家! 同......
  • ArkUI开发趣味体验,快来抽取限量HarmonyOS专属头像!
    本次ArkUI开发趣味体验活动,将手把手教大家如何在IDE里实操一个ArkUI程序,通过补充缺失代码,成功运行程序开启抽奖功能,抽取个人专属头像,做HarmonyOS第一批数字藏品家!同时本期提......
  • 指针趣味小题
    这小段代码帮助理解下指针和对象的大小,&和*的作用#include<stdio.h>#include<iostream>#defineTElemTypeint//构造结点的结构体typedefstructBiTNode{TElemType......
  • LOJ #2589. 「NOIP2009」Hankson 的趣味题
    题目链接:​​传送门​​分析题目要求,,也就是说是的因子,是的因子直接枚举(也就是的因子),另外一个就是然后满足上面两个条件的就,注意判断和相等的情况毫无技术含量#include<......
  • Python OpenCV4趣味应用系列(一)---伪彩色效果
    工欲善其事,必先利其器!起航之前先把环境搭建好:第一步:安装Python,官网下载,选个python3.x(自己喜欢的版本),同时将Python相关目录添加到环境变量;第二步:安装python-opencv,cmd命令......