请编写程序,由系统随机产生一个正整数 n(1<n<50000),根据菜单提示,选择输出小于 n 的以下 7 种特殊数据中的一种:(1)完全数,(2)亲密数,(3)水仙花数,(4)阶乘和数,(5)自守数,(6)孪生素数;直到用户退出系统。
【功能要求】
1、采用 1 行输出 5 个数据的格式。
2、主函数实现正整数 n 的随机产生和菜单的显示,如图1所示。数据 n 作为函数的实参传递给各个子函数。
3、子函数实现 1 到 n 之间的特殊数据的判断和输出,不同类型特殊数据的判断用不同子函数实现。
【难点与提示】
1、各类特殊数据的解释如下
(1)完全数是恰好等于自身的因子之和的数,例如 6 是完全数,因为6=1*2*3=1+2+3。
(2)亲密数是两个正整数,其中一个整数的全部因子之和等于另一个(因子中不计本身),例如 220 和 284 是亲密数, 因为 220 的全部因子是 1,2,4,5,10,11,20,22,44,55,110,和为 284;而 284 的全部因子是 1,2,4,71,142,和为 220。
(3)水仙花数是恰好等于自身各位数字立方和的数,例如 153 是水仙花数,因为153=13+53+33。
(4)阶乘和数是恰好等于自身各位数字阶乘的和的数,例如 145 是阶乘和数,因为145=1!+4!+5!。
(5)自守数是平方后尾部数字是自身的数,例如 9376 是,因为 93762=87909376。
(6)孪生素数是差 2 的两个素数,例如 197 和 199。
2、建议编写一个函数求出某数的因子和,以减少求完全数和亲密数函数中的重复代码。
3、自守数中整数 x 尾部数字的求法:x%10 表示 x 的最后一位数字,x%100 表示 x 的最后两位数字,x%1000 表示 x 的最后三位数字,以此类推。
4、C 编译器提供了基于 ANSI 标准的伪随机数发生器函数 rand()和 srand(),用来生成随机数。这二个函数的工作过程如下:
srand()提供一个种子,它是一个 unsigned int 类型,其取值范围从 065535;32767 之间的随机数程序: 例 1:#include <stdlib.h>
然后调用 rand(),它会根据提供给 srand()的种子值返回一个随机数(在 0 到 32767 之间);
根据需要多次调用 rand(),从而不间断地得到新的随机数;
无论什么时候,都可以给 srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。
例 1 是 0
#include <stdio.h>
#include <time.h> //使用当前时钟做种子void main( void )
{
int i;
srand( (unsigned)time( NULL ) ); //初始化随机数for( i = 0; i < 10;i++ ) //打印出 10 个随机数
printf( " %d\n", rand() );
}
参照上述程序随机生成正整数 n(1<n<50000)。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
//指数
int power(int n,int k)
{
int m = 1;
for(int i=1;i<=k;i++)
m*=n;
return m;
}
//素数
int isprime(int n)
{
if(n<2)
return 0;
for(int i=2;i*i<=n;i++)
if(n%i==0)
return 0;
return 1;
}
//阶乘
int jc(int n)
{
int m=1;
for(int i=1;i<=n;i++)
m*=i;
return m;
}
//因子和
int yzh(int n)
{
int sum = 0;
for(int i=1;i<n;i++)
if(n%i==0)
sum += i;
return sum;
}
//计算位数
int nums(int n)
{
int m = 0;
while(n>0)
{
m++;
n/=10;
}
return m;
}
/////////////////////
//安全数
void Perfect(int n)
{
int count = 0;
for(int i=1;i<=n;i++)
{
if(yzh(i) == i)
{
count++;
printf("%d ",i);
if(count % 5==0)
printf("\n");
}
}
if(count % 5 != 0)
printf("\n");
}
//亲密数
void Amicable(int n)
{
int count = 0;
for(int i=1;i<=n;i++)
{
int m = yzh(i);
int k = yzh(m);
if(i==k)
{
count++;
printf("%d ",i);
if(count % 5==0)
printf("\n");
}
}
if(count % 5 != 0)
printf("\n");
}
//水仙花数
void Narcissistic(int n)
{
int count = 0;
for(int i=1;i<=n;i++)
{
int m = nums(i);
int sum = 0;
int k = i;
while(k>0)
{
sum += power(k%10,m);
k/=10;
}
if(sum == i)
{
count++;
printf("%d ",i);
if(count % 5==0)
printf("\n");
}
}
if(count % 5 != 0)
printf("\n");
}
//阶乘和
void jcsum(int n)
{
int count = 0;
for(int i=1;i<=n;i++)
{
int sum = 0;
int k = i;
while(k>0)
{
sum += jc(k%10);
k/=10;
}
if(sum == i)
{
count++;
printf("%d ",i);
if(count % 5==0)
printf("\n");
}
}
if(count % 5 != 0)
printf("\n");
}
void autoguard(int n)
{
int count = 0;
for(int i=1;i<=n;i++)
{
long long m = i*i;
if(m%power(10,nums(i)) == i)
{
count++;
printf("%d ",i);
if(count % 5==0)
printf("\n");
}
}
if(count % 5 != 0)
printf("\n");
}
void twinprime(int n)
{
int count = 0;
for(int i=1;i<=n-2;i++)
{
if(isprime(i) && isprime(i+2))
{
count++;
printf("%d ",i);
if(count % 5==0)
printf("\n");
}
}
if(count % 5 != 0)
printf("\n");
}
void menu()
{
printf("****************************\n");
printf(" 1.输出完全数\n");
printf(" 2.输出亲密数\n");
printf(" 3.输出水仙花数\n");
printf(" 4.输出阶乘和数\n");
printf(" 5.输出自守数\n");
printf(" 6.输出孪生素数\n");
printf(" 0.退出\n");
printf("****************************\n");
}
int main()
{
srand(time(NULL));
while(1)
{
system("cls");
int n = rand()%50000+1;
printf("请输入n:%d\n",n);
menu();
printf("请输入选择:");
int sel;
scanf("%d",&sel);
switch(sel)
{
case 1:
Perfect(n);
break;
case 2:
Amicable(n);
break;
case 3:
Narcissistic(n);
break;
case 4:
jcsum(n);
break;
case 5:
autoguard(n);
break;
case 6:
twinprime(n);
break;
case 0:
return 0;
default:
printf("输入错误!\n");
break;
}
system("pause");
}
return 0;
}
看来不需要了