题目描述
所谓水仙花数,是指一个n位的正整数,其各位数字的n次方和等于该数本身。
例如153是水仙花数,153是一个3位数,并且153 = 1^3^ + 5^3^ + 3^3^。
输入描述
第一行输入一个整数n,表示一个n位的正整数。n在3到7之间,包含3和7。
第二行输入一个正整数m,表示需要返回第m个水仙花数。
输出描述
返回长度是n的第m个水仙花数。个数从0开始编号。
若m大于水仙花数的个数,返回最后一个水仙花数和m的乘积。
若输入不合法,返回-1。
运行结果
- 输入:4 1 输出:8208 说明:8208是第一个水仙花数
- 输入:7 5 输出:49631575 说明:5超出范围,所以最后一个水仙花数和5的乘积
- 输入:8 2 输出:49631575 说明:8超出范围
题目解析
本题的水仙花数最长有7位,这7位很少,我们可以直接提前计算好3~7位的所有水仙花数来配置为字典,进行打表查询,考试时怎么记得有哪些数字是水仙花数字呢,但是我已经写很简单的源码提供:
c
#include<stdio.h>
#include<math.h>
int main() {
int x, y, z, a, b, c, d;
int i;
printf("3位数 -> 水仙花数分别为:");
for (i = 100; i <= 999; i++) {
x = i / 100;
y = i / 10 % 10;
z = i % 10;
if (i == (int) pow(x, 3) + (int) pow(y, 3) + (int) pow(z, 3)) {
printf("%d ", (int) pow(x, 3) + (int) pow(y, 3) + (int) pow(z, 3));
}
}
printf("\n");
printf("4位数 -> 水仙花数分别为:");
for (i = 1000; i <= 9999; i++) {
x = i / 1000;
y = i / 100 % 10;
z = i / 10 % 10;
a = i % 10;
if (i == (int) pow(x, 4) + (int) pow(y, 4) + (int) pow(z, 4) + (int) pow(a, 4)) {
printf("%d ", (int) pow(x, 4) + (int) pow(y, 4) + (int) pow(z, 4) + (int) pow(a, 4));
}
}
printf("\n");
printf("5位数 -> 水仙花数分别为:");
for (i = 12345; i <= 99999; i++) {
x = i / 10000;
y = i / 1000 % 10;
z = i / 100 % 10;
a = i / 10 % 10;
b = i % 10;
if (i == (int) pow(x, 5) + (int) pow(y, 5) + (int) pow(z, 5) + (int) pow(a, 5) + (int) pow(b, 5)) {
printf("%d ", (int) pow(x, 5) + (int) pow(y, 5) + (int) pow(z, 5) + (int) pow(a, 5) + (int) pow(b, 5));
}
}
printf("\n");
printf("6位数 -> 水仙花数分别为:");
for (i = 100000; i <= 999999; i++) {
x = i / 100000;
y = i / 10000 % 10;
z = i / 1000 % 10;
a = i / 100 % 10;
b = i / 10 % 10;
c = i % 10;
if (i == (int) pow(x, 6) + (int) pow(y, 6) + (int) pow(z, 6) + (int) pow(a, 6) + (int) pow(b, 6) + (int) pow(c, 6)) {
printf("%d ", (int) pow(x, 6) + (int) pow(y, 6) + (int) pow(z, 6) + (int) pow(a, 6) + (int) pow(b, 6) + (int) pow(c, 6));
}
}
printf("\n");
printf("7位数 -> 水仙花数分别为:");
for (i = 1000000; i <= 9999999; i++) {
x = i / 1000000;
y = i / 100000 % 10;
z = i / 10000 % 10;
a = i / 1000 % 10;
b = i / 100 % 10;
c = i / 10 % 10;
d = i % 10;
if (i == (int) pow(x, 7) + (int) pow(y, 7) + (int) pow(z, 7) + (int) pow(a, 7) + (int) pow(b, 7) + (int) pow(c, 7) + (int) pow(d, 7)) {
printf("%d ", (int) pow(x, 7) + (int) pow(y, 7) + (int) pow(z, 7) + (int) pow(a, 7) + (int) pow(b, 7) + (int) pow(c, 7) + (int) pow(d, 7));
}
}
return 0;
}

我们可以看到所有水仙花数,直接复制进行打表法,这道题实现逻辑并不难,大家可以看下面算法源码
C算法源码
c
#include<stdio.h>
int main() {
int n, m;
scanf("%d", &n);
scanf("%d", &m);
if (3 <= n && 7 >= n && 0 <= m) {
int daffodil[8][8];
int daffodilSize[8];
daffodil[3][0] = 153; daffodil[3][1] = 370; daffodil[3][2] = 371; daffodil[3][3] = 407;
daffodilSize[3] = 4;
daffodil[4][0] = 1634; daffodil[4][1] = 8208; daffodil[4][2] = 9474;
daffodilSize[4] = 3;
daffodil[5][0] = 54748; daffodil[5][1] = 92727; daffodil[5][2] = 93084;
daffodilSize[5] = 3;
daffodil[6][0] = 548834;
daffodilSize[6] = 1;
daffodil[7][0] = 1741725; daffodil[7][1] = 4210818; daffodil[7][2] = 9800817; daffodil[7][3] = 9926315;
daffodilSize[7] = 4;
if (m < daffodilSize[n]) {
printf("%d", daffodil[n][m]);
} else {
printf("%lld", (long long) daffodil[n][daffodilSize[n] - 1] * m);
}
} else {
printf("-1");
}
return 0;
}