最大公约数和最小公倍数问题
2015-10-24 15:55
375 查看
题目背景 NOIP2001 普及组 题目描述 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1.P,A是正整数 2.要求P,Q以x0为最大公约数,以y0为最小公倍数. 试求:满足条件的所有可能的两个正整数的个数.
为了响应勤俭节约的号召,我就不描述题目了。
这是一道很简单的题,没错。然而在我研究gcd和lcm之前,是完全不会。。。好吧好吧,现在研究会了就行了。
这道题就是,如果暴力求解,就会TLE
首先要知道公式lcm(a,b)=a*b/gcd(a,b),(具体到下方讨论)然后就可以根据一个值求另一个了。只需要枚举i,不需要枚举j。然而还可以再优化,也就是,i一定是gcd的倍数,i可以一次性加上gcd。加完之后,需要判断是否可以使用这个i。可以的话就让tot+1
#include<iostream> using namespace std; inline int gcd(int a,int b){ //求gcd的算法。inline是用来加速的 if(b==0)return a; return gcd(b,a%b); } int main(){ int n,m,tot=0; cin>>n>>m; //m是lcm,n是gcd for(int i=n;i<=m;i+=n){ //枚举i if(m%i==0){ //如果lcm根本就不是i的倍数,也就不用求了 int j=(n*m)/i; //根据上面那个公式推出的求j公式 if(gcd(i,j)==n)tot++; //即使有j,i和j也不一定会gcd给出的m } } cout<<tot; }
而lcm(a,b)=a*b/gcd(a,b)呢,就需要以下证明
a的质因数集:{a0,a1……an}
b的质因数集:{b0,b1……bn}
存在am1=bn1,am2=bn2……
所以gcd(a,b)=am1*am2……
lcm(a,b)=a*b/(am1……)出去两个集合相同的元素,也就是gcd(a,b)
相关文章推荐
- Bellman-Ford算法详讲
- 每天一个linux命令(16):mv命令
- 基于Netty的服务端长连接
- win8系统下如何给文件夹加密 win8系统文件夹加密保护文件安全的方法[附加密软件]
- Java-HttpServletRequest
- Java-HttpServletRequest
- Android:Android中的Surface和SurfaceView
- OC01 类和对象
- Java-HttpServletRequest
- 海量数据等概率选取问题
- 路由表结构与路由的查找过程
- 一看就会Android之开发自定义的View
- 等概率随机排列数组(洗牌算法)
- C语言localtime()函数:获取当前时间和日期并转换为本地时间
- Linux学习 - vsftpd的配置和常用命令
- html页面例子
- 微信浏览器内建的WeixinJSBridge 实现“返回”操作 WeixinJSBridge.call('closeWindow');
- 一看就会Android之布局高度和布局宽度与组件高度和宽度的区别
- swift闭包的理解
- hdu 5505 GT and numbers【BestCoder Round #60】