博客
关于我
P1072 Hankson 的趣味题 数学或者模拟【1】
阅读量:215 次
发布时间:2019-02-28

本文共 2686 字,大约阅读时间需要 8 分钟。

题目描述  

Hanks 博士是 BT(Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。

今天在课堂上,老师讲解了如何求两个正整数c1​ 和c2​ 的最大公约数和最小公倍数。现在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0​,a1​,b0​,b1​,设某未知正整数x 满足:

1. x 和 a0​ 的最大公约数是 a1​;

2. x和 b0​ 的最小公倍数是b1​。

Hankson 的“逆问题”就是求出满足条件的正整数x。但稍加思索之后,他发现这样的x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x的个数。请你帮助他编程求解这个问题。

输入输出格式

输入格式:

 

第一行为一个正整数 n,表示有 n 组输入数据。接下来的n 行每行一组输入数据,为四个正整数a0​,a1​,b0​,b1​,每两个整数之间用一个空格隔开。输入数据保证a0​ 能被a1​ 整除,b1​ 能被b0​整除。

 

输出格式:

 

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

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

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

 

输入输出样例

输入样例#1: 复制

2 41 1 96 288 95 1 37 1776

输出样例#1: 复制

6 2

说明

【说明】

第一组输入数据,xx可以是 9,18,36,72,144,2889,18,36,72,144,288,共有66 个。

第二组输入数据,xx 可以是48,177648,1776,共有 22 个。

 

NOIP 2009 提高组 第二题

我的思路,将b1和b0分解,相同部分是可选的,不同部分需要取b1中的,然后就是根据最小公倍数原理得到可能的x,之后带入最大公约数进行判断。完全是过程模拟。 80分,另外两个超时。

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;int n;ll a0,a1,b0,b1;set
res;map
vb1,vb0,iselect; //可选部分ll imust=1; //必须有的部分map
factor(ll num){ bool isgo=true; map
mp; while(isgo) { ll r=(num); isgo=false; for(int i=2; i
::iterator it=iselect.begin(); for(int i=0; i
a) { t = a; a = b; b = t; } while ((r = a%b) != 0) { a = b; b = r; } return(b);}int main(){ cin>>n; while(n--) { //cin>>a0>>a1>>b0>>b1; scanf("%lld %lld %lld %lld",&a0,&a1,&b0,&b1); vb1.clear(); vb0.clear(); imust=1; iselect.clear(); res.clear(); vb1=factor(b1); vb0=factor(b0); map
::iterator it; for(it=vb1.begin(); it!=vb1.end(); it++) { ll t=(*it).first; if(vb0.count(t)&&vb0[t]==vb1[t]) { //这个元素 两个都有且个数相同 iselect[it->first]=it->second; } else { for(int j=0; j<(*it).second; j++) imust*=t; } } dfs(imust,0,iselect.size()); int count=0; for(set
::iterator it=res.begin(); it!=res.end(); it++) { if(gcd(*it,a0)==a1) { count=count+1; } } cout<
<

牛人的代码

  • 首先来分析一下这个题目

证明:

  • 把上面的结论推广一下,得到结论PP

对于两个正整数a,b,设gcd(a,b)=k,则存在gcd(a/k,b/k)=1

  • 应用结论PP

  • 整理一下式子

用心体会这两个式子,你会发现x是a1​的整数倍而且是b1​的因子

好像这个由gcd和 lcm也可以得到?嗯,就这样于是得到一种解题思路

√1b1 枚举b1 的因子(也就是 x ),如果这个数是 a1 的整数倍,并且满足那两个式子,ans++
#include
using namespace std;int gcd(int a,int b) { return b==0?a:gcd(b,a%b);}int main() { int T; scanf("%d",&T); while(T--) { int a0,a1,b0,b1; scanf("%d%d%d%d",&a0,&a1,&b0,&b1); int p=a0/a1,q=b1/b0,ans=0; for(int x=1;x*x<=b1;x++) if(b1%x==0){ if(x%a1==0&&gcd(x/a1,p)==1&&gcd(q,b1/x)==1) ans++; int y=b1/x;//得到另一个因子 if(x==y) continue; if(y%a1==0&&gcd(y/a1,p)==1&&gcd(q,b1/y)==1) ans++; } printf("%d\n",ans); } return 0;}

 

转载地址:http://qvki.baihongyu.com/

你可能感兴趣的文章
mongodb定时备份数据库
查看>>
mppt算法详解-ChatGPT4o作答
查看>>
mpvue的使用(一)必要的开发环境
查看>>
MQ 重复消费如何解决?
查看>>
mqtt broker服务端
查看>>
MQTT 保留消息
查看>>
MQTT 持久会话与 Clean Session 详解
查看>>
MQTT介绍及与其他协议的比较
查看>>
MQTT工作笔记0007---剩余长度
查看>>
MQTT工作笔记0008---服务质量
查看>>
MQTT工作笔记0009---订阅主题和订阅确认
查看>>
Mqtt搭建代理服务器进行通信-浅析
查看>>
MS COCO数据集介绍
查看>>
MS Edge浏览器“STATUS_INVALID_IMAGE_HASH“兼容性问题
查看>>
ms sql server 2008 sp2更新异常
查看>>
MS SQL查询库、表、列数据结构信息汇总
查看>>
MS UC 2013-0-Prepare Tool
查看>>
MSBuild 教程(2)
查看>>
msbuild发布web应用程序
查看>>
MSB与LSB
查看>>