算数基本定理(求一个数所有约数的个数)——一道OJ题目
来源:互联网 发布:点胶机编程步骤 编辑:程序博客网 时间:2024/05/16 04:49
算数基本定理
大约公元前350年,欧几里得在他伟大的十三卷著作《原本》中,用了许多篇幅来讨论素数。特别是他证明了每一个比1大的数(即每个比1大的正整数)要么本身是一个素数,要么可以写成一系列素数的乘积,如果不考虑这些素数的在乘积中的顺序,那么写出来的形式是唯一的。
例如:14=2×7,21=3×7,等等。
等号右边的表达式分别是数14与21的“素数分解”。这样我们能把欧几里得的结果表达为:每一个大于1的奇数要么是素数,要么具有唯一的(次序变化不计)素数分解。这个事实被称为算术基本定理,它告诉我们素数好比化学家的原子——所有整数得以构成的基本砌块。
算术基本定理(The fundamental theorem of arithmetic) 即唯一分解定理, 告诉我们每一个大于1 的整数若不是质数都可以写成有限多个质因子的乘积且经过适当排序其写法唯一。
以下是一道OJ题目,网址:http://ac.jobdu.com/problem.php?pid=1493
/*题目描述:给定两个正整数a,b(1<=a,b<=100000000),计算他们公约数的个数。如给定正整数8和16,他们的公约数有:1、2、4、8,所以输出为4。输入:输入包含多组测试数据,每组测试数据一行,包含两个整数a,b。输出:对于每组测试数据,输出为一个整数,表示a和b的公约数个数。样例输入:8 1622 16样例输出:42*/
解法一:
思路:要求所有公约数的个数,我们可以先用辗转相除法求出最大公约数,然后求出这个最大公约数的所有约数的个数,也即a和b的公约数的个数
#include <cstdio>#include <iostream>using namespace std;int main(){int a,b,temp;int count,max,i;freopen("f:/in.txt","r",stdin);while(~scanf("%d%d",&a,&b)){while(a%b!=0){temp=a%b;a=b;b=temp;} //辗转相除法求出最大公约数 max=b;count=0;if(max==1){printf("1\n");continue;}for(i=1;i<max;i++){if(b%i==0){count++;max=b/i; //由于该题卡时间,此处同时找到两个约数,减少遍历范围if(max!=i) count++;}}printf("%d\n",count);}fclose(stdin);return 0;}解法二:
对a、b分别分解成质因子,然后根据算数基本定理,求出公约数个数。
#include <cstdio>#include <iostream>#include <map>#include <set>using namespace std;int min(int a,int b){if(a>b)return b;return a;}int main(){map<int,int> fa,fb;set<int> h;int a,b,count,ct;freopen("f:/in.txt","r",stdin);while(~scanf("%d%d",&a,&b)){fa.clear();fb.clear();h.clear();//分解afor(int i=2;i*i<=a;i++){if(a%i==0){h.insert(i);//存放质数因子//求该质数因子的个数,存入mapwhile(a%i==0){fa[i]++;a/=i;}}}if(a>1) {fa[a]++;//最后一个质数因子h.insert(a);}//分解bfor(int j=2;j*j<=b;j++){while(b%j==0) //求该质数因子个数{fb[j]++; b/=j;}}if(b>1) fb[b]++;//最后一个质数因子count=0;set<int>::iterator it;count=1;for(it=h.begin();it!=h.end();it++){//若有n个相同的m质数因子,则有n+1种组合方式(0个m、1个m.....n个m),每一张组合与其后的其他质数因子的组合之一都形成一个约数ct=min(fa[*it],fb[*it])+1; count*=ct;}printf("%d\n",count); // 1本身也是公约数}fclose(stdin);return 0;}
- 算数基本定理(求一个数所有约数的个数)——一道OJ题目
- zstu oj 4274 约素(求一个数约数的个数)(暴力法)
- 求一个数的约数个数!
- 求一个数约数的个数
- 第一章 基本语法-6循环(for)练习 求一个数的所有约数
- 九度OJ—题目1087:约数的个数
- 求一个数的所有约数
- 求一个数的所有约数
- 求一个数的所有正整数的所有约数
- hdu 1215 七夕节(求一个数所有约数)
- 求一个数的约数
- 求一个数的约数
- hnnu 11546 Sum of f(x) (求一个数的所有约数和)
- 给个n,求1到n的所有数的约数个数的和~
- 给个n,求1到n的所有数的约数个数的和~
- 一道简单的求约数的个数问题
- 九度oj 题目1087:约数的个数
- 九度OJ 题目1087:约数的个数
- eclipse远程调试在linux下运行的程序
- [转]ubuntu修改系统语言
- AJAX - onreadystatechange 事件
- win7休眠的开启与关闭方法
- Android自动化测试在多种屏幕下的注意事项
- 算数基本定理(求一个数所有约数的个数)——一道OJ题目
- textview的使用(别人的例子,我用来 参考的)
- android中设置TabHost当中的字体的方法
- 实现《火炬之光》中的遮挡效果
- 业务主键 Vs. 逻辑主键,到底哪个好?
- ANDROID GRIDVIEW宫格视图(一) 运用--BASEADAPTER
- oracle数据库启动方式及应用场景
- [gkk]传智的jdk7的新特性
- 设计模式之桥接模式(Bridge)