PAT 循环-11. 水仙花数(20) 快速 非直接打印结果

【原题】
水仙花数是指一个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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值