算法在数学中应用2

回文素数

回文素数是指,对一个整数n从左向右和从右向左读其结果值相同且是素数,即称n为回文素数。

通过3个循环变量分别表示1000以内的数百位,十位,个位,由这3个组成一个数,再按照倒序组成一个数。如果两个数相等,则表示该数是一个回文数,再判断该数是否为素数,最后输出找到的数

#include<stdio.h>
#define MAXNUM 1000      //寻找回文数的范围  

int PrimeNum(int i)          //判断是否是素数
{
   int j,flag=1;
   for(j=2;j<i-1;j++){      //循环整除每一个数
      if(i%j==0){        //i能被j整除,表示不是质数
	     flag=0;
		 break;
	  }
   }
   return flag;
}       
int main()
{
   int i,j,t,k,s;
   printf("%d以内的回文素数有:\n",MAXNUM);
   for(i=0;i<=9;++i)            //百位
      for(j=0;j<=9;++j){          //十位
	     if(i==0&&j==0){    //如果百位,十位都为0
		   continue;		   //重新循环
		 }
		 for(k=0;k<=9;k++){    //个位
		     if(i!=0&&i!=k){   //若百位不为0,且百位和个位不等
			   continue;   //重新循环
		 }
		 s=i*100+j*10+k;      //组合成一个整数
		 t=k*100+j*10+i;       //组合成反序数
		 if(i==0){              //整数的第一位为0,是二位整数
		    t/=10;              //调整反向组成的数
		 }
		 if(s>10&&s==t){         //若大于10且为回文数
		    if(PrimeNum(s)==1){   //如果这个回文数是素数
			   printf("%d\t",s);   
			}
			}
	  }
	  }
   printf("\n");
   return 0;
}

平方回文数

平方回文数是指,一个数的平方是一个回文数。例如11*11=121,111*111=12321,1111*1111=1234321,122*122=484

先由数n计算其平方值s,再使用判断回文数的方法来判定s是否为n 的反序数。如果再逐位比较中某一次比较不相同,则表示数s不是一个回文数,接着处理下一个数

#include<stdio.h>
#define MAXNUM 1000
int main()
{
  int n,high,low,count=0;
  int b[10];
  long s;
  printf("序号\t数值\t回文数\n");
  for(n=10;n<MAXNUM;n++){   //循环指定范围
     s=n*n;   //计算n的平方
	 high=0;
	 while(s>0){
	    b[high++]=s%10;
	    s/=10;
	 }
	 low=-1;             //低位指示器
	 while(++low<--high){    //high为高位指示器
	     if(b[low]!=b[high]){   //若高位和低位不相等,则不对称
		     break;   //退出循环
		 }
	 }
	 if(low>=high)    //所有高位和低位都比较后退出循环
	   printf("%2d\t%d\t%d\n",++count,n,n*n);   //输出n和回文数
  }
  return 0;
}

用递归计算阶乘

阶乘关系 n!=n*(n-1)!

#include<stdio.h>
unsigned long factorial(unsigned long n)
{
   if(n<0)
      return 1;
   if(n==1)
       return 1;
	else
	   return (unsigned long)n*factorial(n-1);
}

int main()
{
  unsigned long n;
  printf("输入一个整数(n>0),将会计算其阶乘\n");
  scanf("%d",&n);
  printf("%lu!=%lu\n",n,factorial(n));
  return 0;
}

大数阶乘

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
void carry(int bit[],int pos)  //计算进位
{
   int i,carry=0;
   for(i=0;i<=pos;i++){   //从0~pos逐位检查是否需要进位
     bit[i]+=carry;    //累加进位
	 if(bit[i]<=9){
	    carry=0;              //小于9不进位
	 }
	 else if(bit[i]>9&&i<pos){         //大于9但是不是最高位
	    carry=bit[i]/10;                 //保存进位值
		bit[i]=bit[i]%10;               //得到该位的一位数
	 }
	 else if(bit[i]>9&&i>=pos){    //大于9且是最高位
	   while(bit[i]>9) {           //循环向前进位
	   carry=bit[i]/10;     //计算进位值
	   bit[i]=bit[i]%10;        //当前的一位数
	   i++;
	   bit[i]=carry;               //在下一位保存进位的值
	   }
	 }
   }
}
int  main()
{
  int num,pos,digit,i,j,m,n;
  double sum=0;
  int *fact;
  printf("输入计算其阶乘的数: Num=");
  scanf("%d",&num);
  for(i=1;i<num;i++){   //计算阶乘的位数
    sum+=log10(i);
  }
  digit=(int)sum+1;               //数据长度
  if(!(fact=(int *)malloc((digit+1)*sizeof(int)))){  //分配保存阶乘位数的内存
     printf("分配内存失败!\n");
	 return 0;
  }
  for(i=0;i<=digit;i++){   //初始化数组
     fact[i]=0; 
  }
  fact[0]=1;       //设个位为1
  for(i=2;i<=num;i++){   //将2~num逐个与原来的积相乘
     for(j=digit;j>=0;j--){   //查找最高位
	    if(fact[j]!=0){
		pos=j;                //记录最高位
		break;
		}
	 }
	 for(j=0;j<=pos;j++){
	   fact[j]*=i;           //每一位与i相乘
	 }
	 carry(fact,pos);             //进位处理
	 }
	 for(j=digit;j>=0;j--){   //查找最高位
	     if(fact[j]!=0){
		  pos=j;              //记录最高位
		  break;
		 }
	 }
	 m=0;               //统计输出位数
	 n=0;                 //统计输出行数
	 printf("\n输出%d的阶乘结果(任意键显示下一屏):\n",num);
	 for(i=pos;i>=0;i--){   //输出结果
	 printf("%d",fact[i]);
	 m++;
	 if(m%5==0){            //每5个数输出一个空格,方便阅读
	   printf(" ");
	 }
	 if(m==40){  //每行输出40个数
	 printf("\n");
	 m=0;
	 n++;
	 if(n==10){    //输出10行则暂停
	 getchar();
	 printf("\n");
	 n=0;
	 }
	 }
	 }
	 printf("\n\n");
	 printf("%d的阶乘共有%d位。\n",num,pos+1);
	 getchar();
	 return 0;
}

新浪和新娘问题

有3对新婚夫妇参加婚礼,3个新郎为A,B,C,3个新娘为X,Y,Z。有人不知道谁和谁结婚,于是询问了6位新人中的3位,但听到的回答是这样的:A说他将和X结婚,X说她的未婚夫是C;C说她将和Z结婚。这人听到后知道他们在开玩笑,全是假话

#include<stdio.h>
int match(int i,int j,int k,char wife[])
{
   if(wife[i]=='X')   //A和X不能结婚
    return 0;
   if(wife[j]=='X')   //C不和X结婚
    return 0;
   if(wife[k]=='Z')   //C不和Z结婚
    return 0;
   return 1;
}
int main()
{
  char husband[3]={'A','B','C'},wife[3]={'X','Y','Z'};
  int i,j,k;
  for(i=0;i<3;i++){
     for(j=0;j<3;j++){
	    for(k=0;k<3;k++){
		   if(i!=j&&j!=k&&i!=k){      //不能1个新娘配2个新郎
		     if(match(i,j,k,wife)){
			   printf("新郎\t新娘\n");
			   printf("A\t%c\n",wife[i]);
			   printf("B\t%c\n",wife[j]);
			   printf("C\t%c\n",wife[k]);
			 }
		   }
		}
	 }
  }
}

马克思手稿中的数学题

马克思手稿中有一道趣味数学问题,成为了算法中的经典问题。描述如下:有30个人,其中有男人,女人和小孩,在一家饭馆吃饭花了50先令;每个男人花3先令,每个女人花2先令,每个小孩花1先令;问男人,女人和小孩各有几人? 

设x y z分别代表男人,女人,小孩。由题可得到方程  x+y+z=30 (1)     3x+2y+z=50(2)  由(2)-(1)可得 2x+y=20(3)  由(3)可知x的范围是0~10

#include<stdio.h>
int main()
{
  int x,y,z,count=0;
  printf("情况\t男人\t女人\t小孩\n");
  printf("---------------------------\n");
  for(x=0;x<=10;x++){
       y=20-2*x;             //由式子(3)可得
	   z=30-x-y;              //由式子(1)得z
	   if(3*x+2*y+z==50){      //当前情况满足式子(2)
	        printf("%d\t%d\t%d\t%d\n",++count,x,y,z);
	   }
  }
   return 0;
}

    

正整数分解质因数

将一个正整数分解质因数。例如:输入90,打印90=2*3*3*5。

对n进行分解质因数,应先找到一个最小得质数k,然后按下属步骤完成:

(1)如果这个质数恰好等于n,则说明分解质因数得过程已经结束,打印即可

(2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n,重复执行第一步;

(3)如果n不能被k整除,则用k+1作为k值,重复执行第一步。

#include<stdio.h>
int main()
{
  int n,i;
  printf("\n请输入一个正整数将分解质因数\n");
  scanf("%d",&n);
  printf("%d=",n);
  for(i=2;i<=n;i++){
    while(n!=i){
	   if(n%i==0){
	       printf("%d*",i);
		   n=n/i;
	   }
	   else{
	   break;
	   }
	}
  }
  printf("%d",n);
  printf("\n");
  return 0;
}

实现m*n矩阵和n*p矩阵相乘

#include<stdio.h>
#define MAX 10
void MatrixMutiply(int m,int n,int p,long lMatrix1[MAX][MAX],long lMatrix2[MAX][MAX],long lMatrixResult[MAX][MAX])
{
   int i,j,k;
   long lSum;
   for(i=0;i<m;i++){       //嵌套循环计算结果矩阵(m*p)每一个元素
      for(j=0;j<p;j++){            //按照矩阵乘法的跪着计算结果矩阵的i*j元素
	     lSum=0;
		 for(k=0;k<n;k++){
		    lSum+=lMatrix1[i][k]*lMatrix2[k][j];
		 }
			lMatrixResult[i][j]=lSum;
		 }
	  }
}
int main()
{
    long lMatrix1[MAX][MAX],lMatrix2[MAX][MAX];
	long lMatrixResult[MAX][MAX],lTemp;
	int i,j,m,n,p;
	printf("\n输入矩阵1的行数m:\n");
	scanf("%d",&m);
	printf("\n输入矩阵1的列数n:\n");
	scanf("%d",&n);
	printf("\n输入矩阵2的列数p:\n");
	scanf("%d",&p);
	printf("输入矩阵1的元素(%d*%d):\n",m,n);
	for(i=0;i<m;i++){
	   for(j=0;j<n;j++){
	     scanf("%ld",&lTemp);
		 lMatrix1[i][j]=lTemp;
	   }
	}
	printf("输入矩阵2的元素(%d*%d):\n",n,p);
	for(i=0;i<n;i++){
	   for(j=0;j<p;j++){
	     scanf("%ld",&lTemp);
		 lMatrix2[i][j]=lTemp;
	   }
	}
	MatrixMutiply(m,n,p,lMatrix1,lMatrix2,lMatrixResult);
	printf("相乘后的矩阵:\n");
	for(i=0;i<m;i++){
	   for(j=0;j<p;j++){
	     printf("%ld ",lMatrixResult[i][j]);
	   }
	   printf("\n");
	}
	printf("\n");
	return 0;
}

矩阵转置

#include<stdio.h>
#define MAX 10
int main()
{
 long lMatrix[MAX][MAX],lTemp;
 int i,j,n;
 printf("输入矩阵的行数n\n");
 scanf("%d",&n);
 printf("输入矩阵的元素(%d*%d):\n",n,n);
	for(i=0;i<n;i++){
	   for(j=0;j<n;j++){
	     scanf("%ld",&lTemp);
		 lMatrix[i][j]=lTemp;
	   }
	}
	for(i=0;i<n;i++){            //对调a[i][j]和a[j][i]
	  for(j=0;j<i;j++){
	    lTemp=lMatrix[i][j];
		lMatrix[i][j]=lMatrix[j][i];
		lMatrix[j][i]=lTemp;
	  }
	}
	printf("置转后的矩阵:\n");
		for(i=0;i<n;i++){
	   for(j=0;j<n;j++){
	     printf("%ld ",lMatrix[i][j]);
	   }
	   printf("\n");
	}
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41398448/article/details/81570907