【4.61】分析:按照亲密数定义,要判断数a是否有亲密数,只要计算出a的全部因子的累加和为b,再计算b的全部因子的累加和为n,若n等于a则可判定a和b是亲密数。计算数a的各因子的算法:用a依次对i(i=1~a/2)进行模运算,若模运算结果等于0,则i为 a的一个因子;否则结束对a的因子的计算。
参考答案:
#include
#include
main( )
{ int a, i, m, n;
printf("Friendly-numbers pair samller than 3000:\n");
for(a=1;a<3000;a++) /* 穷举3000以内的全部整数 */
{ for(m=0,i=1;i<=a/2;i++ ) /* 计算数a的各因子,各因子之和存于m */
if(!(a%i))
m+=i; /* 计算m的各因子,各因子之和存于n */
for(n=0,i=1;i<=m/2;i++)
if(!(m%i))
n+=i;
if(n==a && a
printf(" %4d~%4d",a,m);
}
【4.62】参考答案:
#include
#include
main( ) /* 猜数程序 */
{ int magic; /* 计算机"想"的数 */
int guess; /* 人猜的数 */
int counter;
magic=rand( ); /* 通过调用随机函数任意"想"一个数 */
guess=magic-1; /* 初始化变量guess的值 */
counter=0; /* 计数器清零 */
while(magic != guess)
{ printf("guess the magic number:");
scanf("%d", &guess); /* 人输入所猜的数 */
counter++;
if(guess>magic)
printf("**** Wrong **** too hight\n");
else if(guess
printf("**** Wrong **** too low\n");
}
printf("**** Right ****\n");
printf("guess counter is %d\n", counter);
}
【4.63】分析:直接计算阶乘的结果显然超出整型数的范围。此题的关键是如何减少计算中数的规模,注意在计算过程中出现0后,我们可以先行统计0的个数,然后将0从结果中移去,另外,结果仅保存个位数即可,其它位的数不会对0的个数产生影响。
参考答案:
main()
{ int i,n=0;
long s=1;
for(i=1;i<=1000;i++)
{ s=s*i;
while(s%10==0)
{ s=s/10;
n++;
}
s=s%10;
}
printf("n=%d,s=%d\n",n,s);
}
【4.64】参考答案:
main()
{ int i,j,b[3][2];
int a[2][3]={{1,2,3},{4,5,6}};
for(i=0;i<=1;i++)
for(j=0;j<=2;j++)
b[j][i]=a[i][j];
for(i=0;i<=2;i++)
{ for(j=0;j<=1;j++)
printf("%d ",b[i][j]);
printf("\n");
}
}
【4.65】参考答案:
main()
{ int i,count=0,a[11]={0,10,2,8,22,16,4,10,6,14,20};
while(1)
{ for(i=1;i<=10;i++)
a[i-1]=a[i-1]/2+a[i]/2;
a[10]=a[10]/2+a[0];
for(i=1;i<=10;i++)
if(a[i]%2==1) a[i]++;
for(i=1;i<10;i++)
if(a[i]!=a[i+1]) break;
if(i==10) break;
else
{ a[0]=0;
count++;
}
}
printf("count=%d number=%d\n",count,a[1]);
}
【4.66】参考答案:
main()
{ int i,j,s1=0,s2=1,a[5][5];
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{ printf("%d %d: ",i,j);
scanf("%d",&a[i][j]);
}
for(i=0;i<5;i++)
{ for(j=0;j<5;j++)
printf("%5d",a[i][j]);
printf("\n");
}
j=0;
for(i=0;i<5;i++)
{ s1=s1+a[i][i];
if(i%2==0) s2=s2*a[i][i];
if(a[i][i]>a[j][j]) j=i;
}
printf("SUN=%d\nACCOM=%d\na[%d]=%d\n",s1,s2,j,a[j][j]);
}
【4.67】参考答案:
#include "stdio.h"
main()
{ int i,n=0,a[4]={0};
printf("Please enter a digit:");
for(i=0;i<4 && (a[i]=getchar())!='\n';i++) ;
for(i=0;i<4;i++)
if(a[i]>=48&&a[i]<=57) a[i]=a[i]-48;
else if(a[i]>=65&&a[i]<=69) a[i]=a[i]-55;
else if(a[i]>=97&&a[i]<=102) a[i]=a[i]-87;
else printf("input Error!");
for(i=0;i<4;i++)
n=n*16+a[i];
printf("%d",n);
}
【4.68】参考答案:
main()
{ int i,n,k=16,a[16]={0};
printf("Please enter a digit:");
scanf("%d",&n);
while(n>0) /* 将十进制数转变为二进制数 */
{ a[--k]=n%2;
n=n/2;
}
for(i=0;i<16;i++)
printf("%2d",a[i]);
}
【4.69】参考答案:
#include
main()
{ int i,j,m,s,k,a[100];
for(i=1;i<=100;i++ ) /* 寻找1000以内的完数 */ { m=i;s=0;k=0;
while(m>0) /* 寻找i的因子 */
{ for(j=1;j
if(m%j==0)
{ s=s+j;
m=m/j;
a[k++]=j;
}
if(j>=m) break;
}
if(s!=0&&i==s+m)
{ a[k++]=m;
for(j=0;j
printf("%4d",a[j]);
printf("==%4d\n",i);
}
}
}
【4.70】参考答案:
main()
{ int i,j,k,n,m=1,r=1,a[2][100]={0}; printf("Please enter n:");
scanf("%d",&n);
for(i=0;i
{ printf("a[%d]= ",i);
scanf("%d",&a[0][i]);
}
while(m<=n) /* m记录已经登记过的数的个数 */
{ for(i=0;i
{ if(a[1][i]!=0) /* 已登记过的数空过 */
continue;
k=i;
for(j=i;j
if(a[1][j]==0 && a[0][j]
a[1][k]=r++; /* 记录名次,r为名次 */
m++; /* 登记过的数增1 */
for(j=0;j
if(a[1][j]==0 && a[0][j]==a[0][k])
{ a[1][j]=a[1][k];
m++;
}
break;
}
}
for(i=0;i
printf("a[%d]=%d, %d\n",i,a[0][i],a[1][i]);
}
【4.71】参考答案:
#include
main()
{ int i,j,k=0,m=2,s,r=0,a[500]; printf("%4d ",m);
for(i=3;i<=2000;i++ )
{ for(j=2;j<=i-1;j++)
if(i%j==0) break;
if(j==i)
{ printf("%4d ", i );
a[k++]=i-m;
m=i;
}
}
for(i=0;i
{ s=0;
for(j=i;j
{ s=s+a[j];
if(s>=1898) break;
}
if(s==1898)
r++;
}
printf("\nresult=%d\n",r);
}
【4.72】分析:本问题的思路很多,我们介绍一种简单快速的算法。
首先求出三位数中不包含0且是某个整数平方的三位数,这样的三位数是不多的。然后将满足条件的三位数进行组合,使得所选出的三个三位数的九个数字没有重复。程序中可以将寻找满足条件三位数的过程和对该三位数进行数字分解的过程结合起来。
参考答案:
#include
main( )
{ int a[20],num[20][3],b[10]; /* a: 存放满足条件的三位数 */
/* num:满足条件的三位数分解后得到的数字,b: 临时工作 */
int i,j,k,m,n,t,flag;
printf("The 3 squares with 3 different digits each are:\n");
for(j=0,i=11;i<=31;i++) /* 求出是平方数的三位数 */
if(i%10 != 0) /* 若不是10的倍数,则分解三位数 */
{ k=i*i; /* 分解该三位数中的每一个数字 */
num[j+1][0]=k/100; /* 百位 */
num[j+1][1]=k/10%10; /* 十位 */
num[j+1][2]=k%10; /* 个位 */
if(!(num[j+1][0]==num[j+1][1] || num[j+1][0]==num[j+1][2]
|| num[j+1][1]==num[j+1][2]) )
/* 若分解的三位数字均不相等 */
a[++j]=k; /* j:计数器,统计已找到的满足要求的三位数 */
}
for(i=1;i<=j-2;++i ) /* 从满足条件的三位数中选出三个进行组合 */
{ b[1]=num[i][0]; /* 取第i个数的三位数字 */
b[2]=num[i][1];
b[3]=num[i][2];
for(t=i+1;t<=j-1;++t)
{ b[4]=num[t][0]; /* 取第t个数的三位数字 */
b[5]=num[t][1];
b[6]=num[t][2];
for(flag=0, m=1;!flag&&m<=3;m++) /* flag:出现数字重复的标记 */
for(n=4;!flag&&n<=6;n++) /* 判断前两个数的数字是否有重复 */
if(b[m]==b[n]) flag=1; /* flag=1:数字有重复 */
if(!flag)
for(k=t+1;k<=j;++k)
{ b[7]=num[k][0]; /* 取第k个数的三位数字 */
b[8]=num[k][1];
b[9]=num[k][2];
/* 判断前两个数的数字是否与第三个数的数字重复 */
for(flag=0,m=1;!flag&&m<=6;m++)
for(n=7;!flag&&n<=9;n++)
if(b[m]==b[n]) flag=1;
if(!flag) /* 若均不重复则打印结果 */
printf("%d, %d, %d\n",a[i],a[t],a[k]);
}
}
}
}
【4.73】参考答案:
main()
{ int i,n,k,a[3],b[3];
for(i=248;i<=343;i++)
{ for(n=i,k=0;n>0;n/=7)
a[k++]=n%7;
for(n=i,k=0;n>0;n/=9)
b[k++]=n%9;
if(k==3)
for(n=0;n
if(a[n]!=b[k-n-1])
break;
if(n==k)
printf("%d\n",i);
}
}
【4.74】参考答案:
#include
int pos[101],div[101];
main ()
{ int m, n, i, j;
printf("Please input m/n(<0
scanf("%d%d", &m,&n);
printf("%d/%d=0.", m, n);
for(i=1;i<=100;i++)
{ pos[m]=i;
m*=10;
div[i]=m/n;
m=m%n;
if(m==0)
{ for( j=1;j<=i;j++) printf("%d",div[j]);
break;
}
if(pos[m]!=0)
{ for( j=1;j<=i;j++) printf("%d",div[j]);
printf("\nloop: start=%d, end=%d",pos[m], i);
break;
}
}
printf("\n");
}
【4.75】参考答案:
#include "stdio.h"
int a[20],b[20];
main()
{ int t=0,*m,*n,*k,*j,z,i=0;
printf("Input number 1:");
do
{ a[++t]=getchar()-'0';
}while(a[t]!=-38);
printf("Input number 2:");
do
{ b[++i]=getchar()-'0';
}while(b[i]!=-38);
if(t>i)
{ m=a+t;n=b+i;j=a;k=b;z=i;
}
else
{ m=b+i;n=a+t;j=b;k=a;z=t;
}
while(m!=j)
{ (*(--n-1))+=(*(--m)+*n)/10;
*m=(*m+*n)%10;
if (n==k+1 && *k!=1 ) break;
if (n==k+1 && *k)
{ n+=19;*(n-1)=1;
}
if (n>k+z && *(n-1)!=1) break;
}
while (*(j++)!=-38) printf("%d",*(j-1));
printf("\n");
}