您的位置:首页 > 其它

一些有趣的数字哦

2020-02-03 04:24 253 查看

上大学后认识了许多词语,其中就包括一些奇奇怪怪的数字们

00最大公约数【Greatest Common Divisor】
0.0欧几里得算法/辗转相除法–递归实现(最快速,某大佬所传授)

int Gcd(int a,int b)  //用辗转相除法来递归求最大公约数
{
return !b ? a : Gcd(b,a%b);
}
/*这一行等价于下面的代码
if(b == 0){
return a;
}else{
return Gcd(b,a%b);
}
*/

0.1穷举法

int Gcd(int a,int b)
{
int i,temp;
if(a<=0||b<=0) return -1;
temp = a<b ? a : b;
for(i=t;i>0;i--){
if(a%i==0||b%i==0) return i;
}
return 1;
}

0.2递归方法
根据最大公约数的如下3条性质,采用递归法编写计算最大公约数的函数Gcd()
在主函数中调用该函数计算并输出从键盘任意输入的两正整数的最大公约数。
性质1 如果a>b,则a和b与a-b和b的最大公约数相同,即Gcd(a, b) = Gcd(a-b, b)
性质2 如果b>a,则a和b与a和b-a的最大公约数相同,即Gcd(a, b) = Gcd(a, b-a)
性质3 如果a=b,则a和b的最大公约数与a值和b值相同,即Gcd(a, b) = a = b

int Gcd(int a, int b)
{
int result;
if(a<=0||b<=0){
return -1;
}
if(a==b){
result = a;
}else if(a>b){
result = Gcd(a-b, b);
}else{
result = Gcd(a, b-a);
}
return result;
}

or

int MaxCommonFactor(int a, int b)
{
if (a <= 0 || b <= 0)
return -1;
while (a != b)
{
if (a > b)
a = a - b;
else if (b > a)
b = b - a;
}
return a;
}

01最小公倍数【Least Common Multiple】
最小公倍数=两数的乘积/最大公约数
如果两个数是倍数关系,则它们的最小公倍数就是较大的数,相邻的两个自然数的最小公倍数是它们的乘积。

int MinCommonMultiple(int a, int b)
{
int i;
for (i=1;i<=a*b; i++)
{
if (i%a==0 && i%b==0){
return i;
}
}
}

02素数【Prime Number】
2.0试商法

int IsPrime(int x)
{
int i;
if(x<=1) return 0;
for(i=2;i<=x-1;i++){
if(x%i==0) goto End;//goto大法好!
}
End:return i<=x-1 ? 0 : 1;//返回0不是,返回1是
}

2.1数学法(测试2~sqrt(x)之间的整数不能整除x)

int isPrime(int x)
{
int flag=1,i;//设置标志变量
int k=(int) sqrt(x);
if(x<=1) flag = 0;
for(i=2;i<=k&&flag;i++)
{
if(x%i==0)
{
flag=0;
break;//不是素数
}
}
return flag;
}

2.3不是素数进行质因分解

void OutputPrimeFactor(int x)//写一个函数
{
int i;
if(!IsPrime(x)){
for(i=2;i<x;i++){
if(x%i==0){
printf("%d*",i);
OutputPrimeFactor(x/i);//递归调用函数
return;//用于在返回值为空的函数中在任意点结束该函数,此处也可使用break;
/*不带返回值的return语句只能用于返回类型为void的函数。
在返回类型为void的函数中,return返回语句不是必需的,
隐式的return发生在函数的最后一个语句完成时。
一般情况下,返回类型是void的函数使用return语句是为了引起函数的强制结束,
这种return的用法类似于循环结构中的break语句。*/
}
}
}
else{
printf("%d",x);//输出最后一个因子(质因数,不能再分解)
}

}
int isFirstFactor = 1,i;
for(i=2;i<fabs(num);i++){//不写函数实现
if(num%i==0){
if(isFirstFactor==0) printf(",");
printf("%d",i);
isFirstFactor = 0;
}
}
printf("\n");

2.4翁恺老师教哒

//去掉偶数后,从3~sqrt(x) ,效率会更高
int isPrime(int x)
{
int ret = 1;
int i;
if(x==1||(x%2==0&&x!=2)) return 0;//x为偶数,立即,否则循环(n-3)/2+1遍
for(i=3;i<sqrt(x);i+=2){		 //只需sqrt(x)遍
if(x%i==0){
ret ==0;
break;
}
}
return ret;
}

2.5翁恺老师教哒–构造素数表
欲构造n以内的素数表–算法(算法不一定和人的思考方式相同):
1.令x为2
2.将2x、3x、4x直至ax<n的数标记为非素数
3.令x为下一个没有被标记为非素数的数,重复2;直至所有的数都已经尝试完毕

//判断是否能被已知的且<x的素数整除即可
#include<stdio.h>
int isPrime(int x,int knownPrime[],int numberOfKnownPrimes)
{
int ret = 1;
int i;
for(i=0;i<numberOfKnownPrimes;i++){
if(x%knownPrime[i]==0){
ret = 0;
break;
}
}
return ret;
}
int main(void)
{
const int number = 10;
int prime[number];
prime[0] = 2;
int count = 1;
int i = 3;
//输出表头
{
int i;
printf("\t\t");
for(i=0;i<number;i++){
printf("%d\t",i);
}
printf("\n");
}
while(count<number){
if(isPrime(i,prime,count)){
prime[count++] = i;//先把i放到第cnt位置上,再把cnt++ ,前人的套路~~
}
//调试语句,可以在里面定义变量i,不会影响外面i
{
printf("i=%d\tcnt=%d\t",i,count);
int i;
for(i = 0;i<number;i++){
printf("%d\t",prime[i]);
}
printf("\n");
}
i++;
}
//五个数字一换行
for(i=0;i<number;i++){
printf("%d",prime[i]);
if((i+1)%5) printf("\t");
else printf("\n");
}
return 0;
}

03回文素数【回文palindrome】
回文数:从前向后读和从后向前读都一样的数
eg.写一个程序来找出范围[a,b](5 <= a < b <= 100,000,000)( 一亿)间的所有回文质数
百度到CSDN某大佬的求法:原文链接
回文数判断:用模除10读出低位数位,然后入队列,然后用整除10删除这个数位,再用模除10读出新的最低位,再入列,再整除10删除这个数位,如此循环,终止条件是整除后已经为0了,这样就表示整个数都已经从低到高位逐位入列了。然后原来的从低位开始出列,出一位就乘10,然后再出一位累加,再乘10,再累加,直到所有的数位都出列,实际上出来的结果就是把原来的数字倒序了一次,由于倒序后仍然是一个数字,所以可以直接将原来的数字和倒序后的数字比较,另外,上面所说借助队列也只是为了说明的更加清晰更加易懂而已,用堆栈来实现是同样的道理,这只是为了构造那个倒序数的一个手段而已,实际上,细心考虑一下,其实可以根本不必借助这些数据结构的,在读出了低位后直接就写入新的那个倒序数就可以了
【原文C++实现,我改动成C实现】

#include <stdio.h>
#include <math.h>
int isPrime(int x)//判断素数
{
int flag=1,i;
int k=(int)(sqrt(x+1));
for(i=2;i<=k;i++)
{
if(x%i==0)
{
flag=0;
break;//不是素数
}
}
if(flag)
return 1;
return 0;
}
int isHuiwen(int x)//判断回文
{
int c,t=0;
c=x;
while(c)
{
t*=10;
t+=c%10;
c/=10;
}
if(t==x)
return 1;
return 0;
}
int main()//主函数
{
int a,b,i;
scanf("%d %d",&a,&b);//惊奇发现本题C++与C只有输入语句不同诶!
//cin>>a>>b就是从键盘输入a,然后再输入b。
for(i=a;i<=b;i++){
if(isHuiwen(i)&&isPrime(i)){
printf("%d\n",i);
}
}
return 0;
}

04同构数 【isomorphism】
正整数n若是它平方数的尾部,则称n为同构数。

#include<stdio.h>
int main()
{
printf("Print all the isomorphism between 1-999:\n");
int i;
for (i = 1; i < 10; i++)
{
if (i*i % 10 == i)
printf("%d\n", i);
}//1-9
for (i = 10; i < 100; i++)
{
if (i*i % 100 == i)
printf("%d\n", i);
}//10-99
for (i = 100; i < 1000; i++)
{
if (i*i % 1000 == i)
printf("%d\n", i);
}//100-999
return 0;
}

05完全数【Perfect number】
又称完美数或完数,它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。(1没有真因子,所以不是完全数。)
1+2+3=6。
1+2+4+7+14=28。
1+2+4+8+16+31+62+124+248=496。

#include<stdio.h>
int IsPerfect(int x);
int main ()
{
int m;
printf("Input m:\n");
scanf("%d", &m);
if (m > 1)
{
if (IsPerfect(m))
printf("%d is a perfect number\n", m);
else
printf("%d is not a perfect number\n", m);
}
else
printf("%d is not a perfect number\n", m);
}
int IsPerfect(int x)
{
int i, sum = 1;
for (i = 2; i < x; i++)
{
if (x % i == 0)
sum =sum+ i;
}
return sum == x?1:0;
}

06爱因斯坦楼梯数【拿来凑数】

#include <stdio.h>
int main()
{
int i=1,find;
do{
i++;
if(i%2==1&&i%3==2&&i%5==4&&i%6==5&i%7==0){
find = 1;
}
}while(find);
printf("x = %d\n",i);
return 0;
}

07组合数
从 n 个不同元素中每次取出 m 个不同元素 ,不管其顺序合成一组,称为从 n 个元素中不重复地选取 m 个元素的一个组合。所有这样的组合的种数称为组合数。
性质C(n,m)= C(n,n-m)

#include <stdio.h>
unsigned long  Fact(unsigned int  n);
int main(){
printf("Input m,k (m>=k>0):");
int m,k;
long ret;
scanf("%d,%d",&m,&k);
do{
printf("Input m,k (m>=k>0):");
scanf("%d,%d",&m,&k);
}while(m<0||k<0||m<k);
ret = (double)Fact(m)/(Fact(k)*Fact(m-k));
printf("The combination is %ld\n",ret);
return 0;
}
unsigned long  Fact(unsigned int  n)
{
if(n==0||n==1){
return 1;
}else{
return n*Fact(n-1);
}

}

静态变量计算n的阶乘

long Fact(int n)
{
static long p=1;
p=p*n;
return p;
}

08斐波那契数列【Fibonacci sequence】

int Fib(int n)
{
if(n==1||n==2){
return 1;
}else{
return Fib(n-1)+Fib(n-2);
}
}

09阿姆斯特朗数【Armstrong Number】
一个n位正整数等于其各位数字的n次方之和,则称为阿姆斯特朗数/自恋性数/n位自方幂数。
eg.1^3 + 5^3 + 3^3 = 153
当n=3时,又称水仙花数,特指一种三位数,其各个数之立方和等于该数。
水仙花数:153、370、371、407。
当n=4时,又称玫瑰花数。玫瑰花数:1634、8208、9474

#include<stdio.h>
int main()
{
printf("There are following Armstrong number smaller than 1000:\n");
int i;
for(i=2;i<=9;i++){
if(i==i*i*i){
printf("%d ",i);
}
}
for(i=10;i<=99;i++){
if(i==(i%10)*(i%10)*(i%10)+(i/10)*(i/10)*(i/10)){
printf("%d ",i);
}
}
for(i=100;i<=999;i++){
if(i==(i%10)*(i%10)*(i%10)+(i/100)*(i/100)*(i/100)+(i/10%10)*(i/10%10)*(i/10%10)){
printf("%d ",i);
}
}
return 0;
}

一个n位正整数如果等于它的n个数字的n次方和,该数称为n位自方幂数。设计求3~6位自方幂数。
**输出格式要求:"%d位自幂数有:" “%ld\t” “\n” (每位完后换行)

程序运行示例如下:
3位自幂数有:153 370 371 407
4位自幂数有:1634 8208 9474
5位自幂数有:54748 92727 93084
6位自幂数有:548834

#include<stdio.h>
#include<math.h>
int main()
{
int a1, a2, a3, a4, a5, a6, i, j;
long m3, m4, m5, m6;
long n3, n4, n5, n6;
static int t[9];
static long s[9][10];
for (a1 = 1; a1 <= 9; a1++)
for (a2 = 0; a2 <= 9; a2++)
for (a3 = 0; a3 <= 9; a3++)
{
m3 = a1 * 100 + a2 * 10 + a3;
n3 = (long)(pow(a1, 3) + pow(a2, 3) + pow(a3, 3));
if (m3 == n3)
{
s[3][++t[3]] = m3;          //三位水仙花数
}
for (a4 = 0; a4 <= 9; a4++)
{
m4 = m3 * 10 + a4;
n4 = (long)(pow(a1, 4) + pow(a2, 4) + pow(a3, 4) + pow(a4, 4));
if (m4 == n4)
{
s[4][++t[4]] = m4;    //四位玫瑰花数
}
for (a5 = 0; a5 <= 9; a5++)
{
m5 = m4 * 10 + a5;
n5 = (long)(pow(a1, 5) + pow(a2, 5) + pow(a3, 5) + pow(a4, 5) + pow(a5, 5));
if (m5 == n5)
{
s[5][++t[5]] = m5; //五位五角星数
}
for (a6 = 0; a6 <= 9; a6++)
{
m6 = m5 * 10 + a6;
n6 = (long)(pow(a1, 6) + pow(a2, 6) + pow(a3, 6) + pow(a4, 6) + pow(a5, 6) + pow(a6, 6));
if (m6 == n6)
{
s[6][++t[6]] = m6; //六位六合数
}
}
}
}
}
for (i = 3; i <= 6; i++)
{
printf("%d位自幂数有:", i);
for (j = 1; j <= t[i]; j++)
{
printf("%ld\t", s[i][j]);
}
printf("\n");
}

return 0;

}

水仙花的求法

#include <stdio.h>
main()
{
int i,t,k,a[4];
printf("There are following Armstrong number smaller than 1000:\n");
for(i=2;i<1000;i++)
{
for(t=0,k=1000;k>=10;t++)
{
a[t]=(i%k)/(k/10);
k/=10;
}
if(a[0]*a[0]*a[0]+a[1]*a[1]*a[1]+a[2]*a[2]*a[2]==i)
printf(" %d ",i);
}
}

玫瑰花数的求法

#include <stdio.h>
#include <math.h>//新鲜的玫瑰花数,心好累啊啊啊啊.....
int main()
{
int i,sum=0,n,t;
for(i=1000;i<=9999;i++){
t = i;
for( ;i>0;i/=10){
n = i%10;
sum += pow(n,4);
}
if(sum==t){
printf("%d	",t);
}
i = t;//这两行
sum =0;//差点要了我的命呜呜呜呜呜呜呜呜
}
return 0;
}

10亲密数
亲密数(相亲数):如果整数A的全部因子(包括1,不包括A本身)之和等于B,且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。
2500年前数学大师毕达哥拉斯就发现,220与284两数之间存在着奇妙的联系:
220的真因数之和为:1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为:1+2+4+71+142=220
毕达哥拉斯把这样的数对称为相亲数。

int FactorSum(int x)// 函数功能:返回x的所有因子之和
{
int i;
int sum = 0;
for (i = 1; i < x; i++)
{
if (x % i == 0)
{
sum = sum + i;
}
}
return sum;
}

设计程序求4位以内的相亲数。
输出格式要求:“相亲数:%d,%d\n”
“%d 的真因数之和为:%d” “+%d” “=%d\n”

#include <math.h>
#include <stdio.h>
int main()
{
int i, j, s, t, s1;
for (i = 11; i <= 9999; i++)
{
s = 1;
t = sqrt(i);
for (j = 2; j <= t; j++)
{
if (i % j == 0)
s = s + j + i / j;
}
if (i == t * t)
s -= t;
if (i < s)
{
s1 = 1;
t = sqrt(s);
for (j = 2; j <= t; j++)
{
if (s % j == 0)
s1 = s1 + j + s / j;
}
if (s == t * t)
s1 -= t;
if (s1 == i)
{
printf("相亲数:%d,%d\n", i, s);
printf("%d 的真因数之和为:%d", i, 1);
for (j = 2; j <= i / 2; j++)
{
if (i % j == 0)
printf("+%d", j);
}
printf("=%d\n", s);
printf("%d 的真因数之和为:%d", s, 1);
for (j = 2; j <= s / 2; j++)
{
if (s % j == 0)
printf("+%d", j);
}
printf("=%d\n", i);
}
}
}
return 0;
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
绀香零八 发布了32 篇原创文章 · 获赞 10 · 访问量 960 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: