7-4 水仙花數
水仙花數是指一個N位正整數(N≥3),它的每個位上的數字的N次冪之和等於它本身。例如:153=13+53+33。本題要求編寫程序,計算所有N位水仙花數。
輸入格式:
輸入在一行中給出一個正整數N(3≤N≤7)。
輸出格式:
按遞增順序輸出所有N位水仙花數,每個數字佔一行。
輸入樣例:
3
輸出樣例:
153
370
371
407
相信許多小夥伴第一眼看到這道題目就想到用循環嵌套了,然後調用一個C語言的次方函數pow(),代碼如下:
#define _CRT_SECURE_NO_DEPRECATE 0
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(){
int n, m;
scanf("%d", &n);
for (int x = 0; x<=9; x++){
for (int y = 0; y <= 9; y++){
for (int z = 0; z <= 9; z++){
for (int j = 0; j <= 9; j++){
for (int i = 0; i <= 9; i++){
for (int k = 0; k <= 9; k++){
for (int h = 0; h <= 9; h++){
if (n == 3 && i * 100 + k * 10 + h == pow((double)i, (double)n) + pow((double)k, (double)n) + pow((double)h, (double)n)){
if ((i * 100 + k * 10 + h)>=100)
printf("%d\n", i * 100 + k * 10 + h);
}
else if (n == 4 && j * 1000 + i * 100 + k * 10 + h == pow((double)j, (double)n) + pow((double)i, (double)n) + pow((double)k, (double)n) + pow((double)h, (double)n)){
if ((j * 1000 + i * 100 + k * 10 + h)>=1000)
printf("%d\n", j * 1000 + i * 100 + k * 10 + h);
}
else if (n == 5 && z * 10000 + j * 1000 + i * 100 + k * 10 + h == pow((double)z, (double)n) + pow((double)j, (double)n) + pow((double)i, (double)n) + pow((double)k, (double)n) + pow((double)h, (double)n)){
if ((z * 10000 + j * 1000 + i * 100 + k * 10 + h)>=10000)
printf("%d\n", z * 10000 + j * 1000 + i * 100 + k * 10 + h);
}
else if (n == 6 && y * 100000 + z * 10000 + j * 1000 + i * 100 + k * 10 + h == pow((double)y, (double)n) + pow((double)z, (double)n) + pow((double)j, (double)n) + pow((double)i, (double)n) + pow((double)k, (double)n) + pow((double)h, (double)n)){
if ((y * 100000 + z * 10000 + j * 1000 + i * 100 + k * 10 + h)>=100000)
printf("%d\n", y * 100000 + z * 10000 + j * 1000 + i * 100 + k * 10 + h);
}
else if (n == 7 && x * 1000000 + y * 100000 + z * 10000 + j * 1000 + i * 100 + k * 10 + h == pow((double)x, (double)n) + pow((double)y, (double)n) + pow((double)z, (double)n) + pow((double)j, (double)n) + pow((double)i, (double)n) + pow((double)k, (double)n) + pow((double)h, (double)n)){
if ((x * 1000000 + y * 100000 + z * 10000 + j * 1000 + i * 100 + k * 10 + h)>=1000000)
printf("%d\n", x * 1000000 + y * 100000 + z * 10000 + j * 1000 + i * 100 + k * 10 + h);
}
}
}
}
if (n == 3){
scanf("%d", &m);
exit(0);
}
}
if (n == 4){
scanf("%d", &m);
exit(0);
}
}
if (n == 5){
scanf("%d", &m);
exit(0);
}
}
if (n == 6){
scanf("%d", &m);
exit(0);
}
}
system("pause");
return 0;
}
結果就是,代碼運行超時了…
然後,我又換了個思路,優化了一下代碼,用一重循環來做,代碼如下:
#define _CRT_SECURE_NO_DEPRECATE 0
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(){
int n, i = 0, j = 1;
scanf("%d", &n);
if (n == 3){
i = 100;
j = 999;
}
if (n == 4){
i = 1000;
j = 9999;
}
if (n == 5){
i = 10000;
j = 99999;
}
if (n == 6){
i = 100000;
j = 999999;
}
if (n == 7){
i = 1000000;
j = 9999999;
}
for (; i <= j; i++){
if (n == 3 && i == pow((double)((i / 100) % 10),(double)(n)) + pow((double)((i / 10) % 10),(double)(n)) + pow((double)(i % 10),(double)(n))){
printf("%d\n", i);
}
if (n == 4 && i == pow((double)((i / 1000) % 10),(double)(n)) + pow((double)((i / 100) % 10),(double)(n)) + pow((double)((i / 10) % 10),(double)(n)) + pow((double)(i % 10),(double)(n))){
printf("%d\n", i);
}
if (n == 5 && i == pow((double)((i / 10000) % 10), (double)(n)) + pow((double)((i / 1000) % 10), (double)(n)) + pow((double)((i / 100) % 10), (double)(n)) + pow((double)((i / 10) % 10), (double)(n)) + pow((double)(i % 10), (double)(n))){
printf("%d\n", i);
}
if (n == 6 && i == pow((double)((i / 100000) % 10), (double)(n)) + pow((double)((i / 10000) % 10), (double)(n)) + pow((double)((i / 1000) % 10), (double)(n)) + pow((double)((i / 100) % 10), (double)(n)) + pow((double)((i / 10) % 10), (double)(n)) + pow((double)(i % 10), (double)(n))){
printf("%d\n", i);
}
if (n == 7 && i == pow((double)((i / 1000000) % 10), (double)(n)) + pow((double)((i / 100000) % 10), (double)(n)) + pow((double)((i / 10000) % 10), (double)(n)) + pow((double)((i / 1000) % 10), (double)(n)) + pow((double)((i / 100) % 10), (double)(n)) + pow((double)((i / 10) % 10), (double)(n)) + pow((double)(i % 10), (double)(n))){
printf("%d\n", i);
}
}
system("pause");
return 0;
}
結果…還是超時
我一琢磨,這應該問題出在pow()這個次方函數上面,於是上網一查,發現這個函數的時間複雜度比我們直接用乘號更大,所以…我直接捨棄了pow()函數,直接用乘號計算次方。
#define _CRT_SECURE_NO_DEPRECATE 0
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(){
int n, i = 0, j = 1;
scanf("%d", &n);
if (n == 3){
i = 100;
j = 999;
}
if (n == 4){
i = 1000;
j = 9999;
}
if (n == 5){
i = 10000;
j = 99999;
}
if (n == 6){
i = 100000;
j = 999999;
}
if (n == 7){
i = 1000000;
j = 9999999;
}
for (; i <= j; i++){
if (n == 3 && i == ((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10) + ((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10) + (i % 10)*(i % 10)*(i % 10)){
printf("%d\n", i);
}
if (n == 4 && i == ((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10) + ((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10) + ((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10) + (i % 10)*(i % 10)*(i % 10)*(i % 10)){
printf("%d\n", i);
}
if (n == 5 && i == ((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10) + ((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10) + ((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10) + ((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10) + (i % 10)*(i % 10)*(i % 10)*(i % 10)*(i % 10)){
printf("%d\n", i);
}
if (n == 6 && i == ((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10) + ((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10) + ((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10) + ((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10) + ((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10) + (i % 10)*(i % 10)*(i % 10)*(i % 10)*(i % 10)*(i % 10)){
printf("%d\n", i);
}
if (n == 7 && i == ((i / 1000000) % 10)*((i / 1000000) % 10)*((i / 1000000) % 10)*((i / 1000000) % 10)*((i / 1000000) % 10)*((i / 1000000) % 10)*((i / 1000000) % 10) + ((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10)*((i / 100000) % 10) + ((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10)*((i / 10000) % 10) + ((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10)*((i / 1000) % 10) + ((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10)*((i / 100) % 10) + ((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10)*((i / 10) % 10) + (i % 10)*(i % 10)*(i % 10)*(i % 10)*(i % 10)*(i % 10)*(i % 10)){
printf("%d\n", i);
}
}
system("pause");
return 0;
}
雖然代碼看起來很長,但是有效地減少了運行時間
注:其實用七重循環嵌套來做也是可以的通過的,只要你將pow()函數改成乘號。