21花朵数

  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 }

 

posted @ 2013-04-14 08:28  萧凡客  阅读(197)  评论(0编辑  收藏  举报