7-4 水仙花數

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()函數改成乘號。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章