7-18 水仙花数
分数 20
全屏浏览题目
切换布局
作者 徐镜春
单位 浙江大学
水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3≤N≤7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
输出样例:
153 370 371 407
正确案例1
#include<stdio.h>
int main()
{
int N,j,m,n=1,min=1,max=1,sum=0;
scanf("%d",&N);
for(int i=1;i<=N;i++){
max*=10;
if(i!=N){min*=10;}
}//求N位数最大值(这里求10的N+1次方,所以下面循环用的< )和最小值
for(int i=min;i<max;i++){
j=i;
while(j>0){
m=j%10;
j/=10;
n=1;//一定记得。也可以在这里int n=1,既省事又不易忘
for(int f=0;f<N;f++){
n*=m;
}//这里分N次得到各个位数的N次方
sum+=n;
}//用for也一样
if(sum==i){printf("%d\n",sum);}
sum=0;
}
return 0;
}
PTA运行超时有可能是循环里用了pow求平方。即为下图
错误案例1
#include<stdio.h>
#include<math.h>
int main()
{
int N,min=1,max=1,sum=0;
scanf("%d",&N);
for(int i=1;i<=N;i++){
max*=10;
if(i!=N){min*=10;}
}
for(int i=min;i<max;i++){
for(int j=i;j>0;j/=10){
int m=j%10;
int n=1;
n=pow(m,N);
sum += n;
}//方便对比,只改了求平方部分
if(sum==i){printf("%d\n",sum);}
sum=0;
}
return 0;
}
评测详情
测试点 提示 内存(KB) 用时(ms) 结果 得分 0 324 6 答案正确
11 / 11 1 440 348 答案正确
3 / 3 2 396 36 答案正确
3 / 3 3 464 2500 运行超时
0 / 3
错误案例2
#include<stdio.h>
#include<math.h>
int main()
{
int N, a, b, c, sum = 0;
int i,m,n;
scanf("%d", &N);
m=pow(10,N-1);n=pow(10,N);
for (i = m; i < n; i++) {
sum=0;
while (i > 0) {
b = i % 10; c = pow(b, N); i /= 10; sum += c;
}//喜提超时*4
if (sum == i) { printf("%d\n", i); }
}
return 0;
}
很抱歉之前对超时问题的归因有很严重的错误,上面的代码四个测试点都超时的原因之前说是用了两次pow(),而这与运行无误的正确案例2有所冲突。故而我很仔细地检查了多次,才发现一个很容易忽略的错误,各位不妨耗费一点点时间找找看。
测试点 提示 内存(KB) 用时(ms) 结果 得分 0 196 2500 运行超时
0 / 11 1 196 2500 运行超时
0 / 3 2 328 2500 运行超时
0 / 3 3 332 2500 运行超时
0 / 3
错误就是 i 在while语句中发生变化,而后续还需要将 i 和sum进行比较
正确案例2
非循环语句中用pow倒是没有影响,如下
#include<stdio.h>
#include<math.h>
int main()
{
int N,min,max,sum=0;
scanf("%d",&N);
min=pow(10,N-1);max=pow(10,N);//这里用pow
for(int i=min;i<max;i++){
for(int j=i;j>0;j/=10){
int m=j%10;
int n=1;
for(int f=0;f<N;f++){n *= m;}
sum += n;
}
if(sum==i){printf("%d\n",sum);}
sum=0;
}
return 0;
}
正确案例3(其实没什么差别,多去敲几次也会出现略微不同的方法)
#include<stdio.h>
#include<math.h>
int main()
{
int N,m=0,n=0;
int a,b,sum=0;
scanf("%d",&N);
n=pow(10,N-1);m=pow(10,N)-1;
for(int i=n;i<=m;i++){
sum=0;
for(int j=i;j>0;j/=10)
{
a=j%10;b=a;//设置一个不会变化的b=a
for(int f=1;f<N;f++){a*=b;}//循环次数为N-1
sum+=a;
}
if(sum==i){printf("%d\n",i);}
}
return 0;
}
时间上会有差异,但都可以通过。
总之要多尝试。平常把踩的坑都填了,测试才不会没有改进方向,一个坑一个坑去试。