回文素数
回文素数是指,对一个整数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;
}