1 #include<stdio.h>
2 #include<time.h>
3 #include<string.h>
4 //#include<conio.h>
5 //#include<math.h>
6 //有的注释 是用来测试数据
7 #define N 21
8 int a[10][N+1];
9 void fun()
10 {
11 int i,temp,j,k,t;
12 memset(a,0,sizeof(a));
13 for(i=1;i<10;i++)
14 {
15 a[i][0]=1;
16 for(j=0;j<N;j++)
17 {
18 temp=0;
19 for(k=0;k<N+1;k++)
20 {
21 t=a[i][k]*i+temp;
22 temp=t/10;
23 a[i][k]=t%10;
24 }
25 }
26 }
27 for(i=0;i<10;i++)
28 {
29 for(j=N-1;j>=0;j--)
30 if(a[i][j]!=0)break;
31
32 a[i][N]=j+1; //记录从第几个开始之后全部为0
33 }
34 //可以在此处输出结果以供检查错误
35 for(i=0;i<10;i++)
36 {
37 printf("i=%d\n",i);
38 for(j=0;j<N+1;j++)
39 printf("%3d",a[i][j]);
40 printf("\n");
41 }
42 }
43 void fun1()
44 {
45 int b[N];
46 int c[N]={0},d[N]={0},e[10]={0};//c[N]存b[N]中每个数字的21次方之和
47 int x,i,j,k,temp,flag; //d[N]存c[N]从大到小排好序的值
48 int f[100][21]; //用来存放满足条件的数 然后从小到大输出
49 for(i=0;i<9;i++) //b[N]存从99……99到100……00之间的数 初始化为9个9后面全是8,因为10个9的21次方之和将超过21位数
50 b[i]=9;
51 for(i=9;i<N;i++)
52 b[i]=8;
53 k=0;//先将满足条件的数组个数清为0
54 while(b[0]!=0) //e[N]存中间排序的中间量 选择的排序方法比较特别(已知最大值的排序)
55 {
56 flag=1;
57
58 //求21个数的21次方之和
59 for(i=0;i<N;i++)
60 {
61 temp=0;
62 for(j=0;j<N;j++)
63 {
64 temp=temp/10+a[b[i]][j]+c[j];
65 c[j]=temp%10;
66 if(j==N-1&&temp>9) //
67 {
68 flag=0;
69 //printf("超过21位数\n");
70 break;
71 }
72 if(a[b[i]][j]==0&&j>=a[b[i]][N])break;//
73 }
74 if(flag==0)break;// 这些都是为了节省时间 进行程序优化
75
76 }
77 //getch();
78 if(c[N-1]==0)flag=0;
79 if(flag)
80 {
81 //将c[N]排序 注意排序方法 复杂度较低
82 x=0;
83 for(i=0;i<N;i++)
84 e[c[i]]++; //分别有几个0到9 存到e[N]中 曾将c[i]错写成b[i]~~
85 for(i=10-1;i>=0;i--)
86 {
87 for(j=0;j<e[i];j++)
88 d[x++]=i;
89 }
90
91 //比较二者是否相等
92 for(i=0;i<N;i++)
93 {
94 if(b[i]!=d[i])
95 {
96 flag=0;
97 break;
98 }
99 }
100 }//if
101 //如果标记falg=1则输出结果
102 if(flag)
103 {
104 /*printf("输出结果为:");
105 for(i=N-1;i>=0;i--)
106 printf("%d",c[i]); 将c[i]曾错写成b[i]
107 printf("\n");若这样输出则为从大到小输出*/
108 j=0;
109 for(i=N-1;i>=0;i--)
110 f[k][j++]=c[i];
111 k++;
112 }
113 //找下一个a[N]
114 for(i=N-1;i>=0;i--)
115 if(b[i]!=0) //此处曾经出错 将b[i]写成a[i]
116 break;
117 temp=b[i];
118 // printf("temp=%d ",temp);
119 while(i<N)
120 {
121 b[i++]=temp-1; //保证去掉重复的数 并按从大到小顺序 进行处理
122 }
123 //printf("b[2]=%d b[3]=%d\n",b[2],b[3]);
124
125 memset(c,0,sizeof(c));//全部置0 因为后面还要用
126 memset(d,0,sizeof(d));
127 memset(e,0,sizeof(e));
128 }
129 //从小到大输出
130 for(i=k-1;i>=0;i--)
131 {
132 for(j=0;j<N;j++)
133 printf("%d",f[i][j]);
134 printf("\n");
135 }
136 }
137 int main()
138 {
139 fun();
140 // fun1();
141
142 printf("\n程序运行了%.2lf秒\n",(double)clock()/CLOCKS_PER_SEC);//只是为了测试一下程序运行的时间
143 return 0;
144 }