【原题】
水仙花数是指一个N位正整数(N>=3),它的每个位上的数字的N次幂之和等于它本身。例 如:153 = 1
3 + 5
3+ 3
3。 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3<=N<=7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:3输出样例:
153 370 371 407
【思路】
从9-0数每个数的个数(个数总和为N),并计算(每个数)N,如果该值是N位的,则判断该数是否为水仙花数。
如N=3,则9-0的个数分别为
9 8 7 6 5 4 3 2 1 0
3 0 0 0 0 0 0 0 0 0
2 1 0 0 0 0 0 0 0 0
2 0 1 0 0 0 0 0 0 0
...
1 2 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0
1 1 0 1 0 0 0 0 0 0
...
0 0 0 0 0 0 0 0 0 3
再进行剪枝判断。
//this code is right with the length of the number no more then 16 #include <stdio.h> #include <iostream> #include <math.h> #include <string> using namespace std; bool compare_word(double number,int *num); int main(void){ int N; cin>>N; double *val = new double [10]; int *num = new int [10]; for (int i=0;i<=9;i++){ val[i]=pow(i*1.0,N); num[i]=0; } double sum[10]; //9,8,7,6,5,4,3,2,1,0 int i,j,k,l,m,n,o,p,q,r; int num_left[10]; double min=pow(10.0,N-1); double max=pow(10.0,N)-1; double flower[100]; int flower_num=0; int s; for (i=N;i>=0;i--){ num[9]=i; num_left[9] = N-num[9]; sum[9]=num[9]*val[9]; if (sum[9]>max) continue; if (num[9]!=0 && sum[9]<min) break; for (j=num_left[9];j>=0;j--){ num[8]=j; num_left[8] = num_left[9]-num[8]; sum[8]=sum[9]+num[8]*val[8]; if (sum[8]>max) continue; if (num[8]!=0 && sum[8]<min) break; for (k=num_left[8];k>=0;k--){ num[7]=k; num_left[7] = num_left[8]-num[7]; sum[7]=sum[8]+num[7]*val[7]; if (sum[7]>max) continue; if (num[7]!=0 && sum[7]<min) break; for (l=num_left[7];l>=0;l--){ num[6]=l; num_left[6] = num_left[7]-num[6]; sum[6]=sum[7]+num[6]*val[6]; if (sum[6]>max) continue; if (num[6]!=0 && sum[6]<min) break; for (m=num_left[6];m>=0;m--){ num[5]=m; num_left[5] = num_left[6]-num[5]; sum[5]=sum[6]+num[5]*val[5]; if (sum[5]>max) continue; if (num[5]!=0 && sum[5]<min) break; for (n=num_left[5];n>=0;n--){ num[4]=n; num_left[4] = num_left[5]-num[4]; sum[4]=sum[5]+num[4]*val[4]; if (sum[4]>max) continue; if (num[4]!=0 && sum[4]<min) break; for (o=num_left[4];o>=0;o--){ num[3]=o; num_left[3] = num_left[4]-num[3]; sum[3]=sum[4]+num[3]*val[3]; if (sum[3]>max) continue; if (num[3]!=0 && sum[3]<min) break; for (p=num_left[3];p>=0;p--){ num[2]=p; num_left[2] = num_left[3]-num[2]; sum[2]=sum[3]+num[2]*val[2]; if (sum[2]>max) continue; if (num[2]!=0 && sum[2]<min) break; for (q=num_left[2];q>=0;q--){ num[1]=q; num_left[1] = num_left[2]-num[1]; sum[1]=sum[2]+num[1]*val[1]; if (sum[1]>max) continue; if (num[1]!=0 && sum[1]<min) break; num[0]=num_left[1]; sum[0]=sum[1]+num[0]*val[0]; if (sum[0]>max) continue; if (num[0]!=0 && sum[0]<min) break; bool flag = compare_word(sum[0],num); if (flag==1){ //cout<<sum[0]<<endl; flower[flower_num]=sum[0]; flower_num++; } } } } } } } } } } for (int i=flower_num-1;i>=0;i--){ printf("%.0f\n",flower[i]); } return 0; } bool compare_word(double number,int *num){ int num1[10],num2[10]; for (int i=0;i<=9;i++){ num1[i]=num[i]; } int temp; bool flag=0; while (true){ //temp=number%10; temp = number - floor(number/10)*10; for (int i=0;i<=9;i++){ if (temp==i){ num1[i]--; if (num1[i]<0){ flag=1; } break; } } if (flag==1) return 0; number=floor(number/10); if (number==0){ break; } } return 1; }