21位水仙花数用java实现

一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数。

例如:

当N=3时,153就满足条件,因为1^3+5^3+3^3=153,这样的数字也被称为水仙花数(其中,“^”表示乘方,5^3表示5的3次方,也就是立方)。

当N=4时,1634满足条件,因为1^4+6^4+3^4+4^4=1634.

当N=5时,92727满足条件。

实际上,对N的每个取值,可能有多个数字满足条件。

程序的任务是:求当N=21时,所有满足条件的水仙花数。注意:这个整数有21位,

它的各个位数字的21次方之和正好等于这个数本身。

如果满足条件的数字不只有一个,请从小到大输出所有符合条件的数字,每个数字占一行。因为这个数字很大,请注意解法时间上的可行性。要求程序在3分钟内运行完毕。

在网上看到很多大侠用c和c++顺利的解决,而且效率还不错,由于自己本身是搞java的,于是在下面用java实现了一遍。
 思路分析:按照我们的习惯性思维,自然会想到穷举法,但事实上,这种方法的时间复杂是显而易见的,一旦程序开始运行,可能一年也难得结束。于是我们换种思维,21位数无非是由0到9这十个数组成的,我们现在要做的事用这十个数字组成21位数,然后计算每一种组合的21次方和,接下来统计和中的各个数字出现的次数是否吻合就行了。
 于是,对于大数据我们可以用java中的BigInteger来处理,免去了自己编写大数据计算函数的时间。于是,我们用九重循环,每一层循环中表示每个数可以出现0到21次,每得到一个数,就累加到sum中去,为了使算法更优化,需要紧接着判断一下sum是否超出了21位,若是就跳出结束。最后判断数据如果是21位数之内,则把得到的sum交给check去判断,check会调用count来统计0到9在sum中出现的次数,如果和循环中提供的0到9出现的频率相等则输出数据,由于在循环中我们是从小到大进行组合,所以最后得出的结果中一定是按照小到大的顺序输出的,省去了再编写排序的函数的时间,再次得到优化。下面给出完整的程序。

import java.math.*; import java.util.HashMap;

public class Test11 {

 private int size = 0;//位数  private BigInteger MAX = null;  private BigInteger MIN = null;  HashMap<String, BigInteger> hm = null;//用来存放0`9的size次方

 public Test11(int length)//构造要求的水仙花的位数  {   this.size = length;   this.MAX = new BigInteger("10").pow(length).subtract(BigInteger.ONE);   this.MIN = new BigInteger("10").pow(length - 1);   this.hm = new HashMap<String, BigInteger>();   for (int i = 0; i <= 9; i++)   {    hm.put(i + "n", new BigInteger(i + "").pow(length));   }  }

 public static void main(String[] args)  {   long start = System.currentTimeMillis();   Test11 test = new Test11(21);   test.find();   long end = System.currentTimeMillis();   long time = end - start;   System.out.println("运行时间: " + time / 10e3 + "秒!");  }

 public void find()  {   BigInteger sum = BigInteger.ZERO;   int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9;//分别是0到9数字出现的次数   for (a9 = 0; a9 <= this.size; a9++)   {    sum = sum.add(this.hm.get("9n").multiply(new BigInteger(a9 + "")));    if (sum.compareTo(MAX) > 0)     break;    for (a8 = 0; a8 <= this.size - a9; a8++)    {     sum = sum.add(this.hm.get("8n").multiply(       new BigInteger(a8 + "")));     if (sum.compareTo(MAX) > 0)      break;     for (a7 = 0; a7 <= this.size - a9 - a8; a7++)     {      sum = sum.add(this.hm.get("7n").multiply(        new BigInteger(a7 + "")));      if (sum.compareTo(MAX) > 0)       break;      for (a6 = 0; a6 <= this.size - a9 - a8 - a7; a6++)      {       sum = sum.add(this.hm.get("6n").multiply(         new BigInteger(a6 + "")));       if (sum.compareTo(MAX) > 0)        break;       for (a5 = 0; a5 <= this.size - a9 - a8 - a7 - a6; a5++)       {        sum = sum.add(this.hm.get("5n").multiply(          new BigInteger(a5 + "")));        if (sum.compareTo(MAX) > 0)         break;        for (a4 = 0; a4 <= this.size - a9 - a8 - a7 - a6          - a5; a4++)        {         sum = sum.add(this.hm.get("4n").multiply(           new BigInteger(a4 + "")));         if (sum.compareTo(MAX) > 0)          break;         for (a3 = 0; a3 <= this.size - a9 - a8 - a7           - a6 - a5 - a4; a3++)         {          sum = sum.add(this.hm.get("3n").multiply(            new BigInteger(a3 + "")));          if (sum.compareTo(MAX) > 0)           break;          for (a2 = 0; a2 <= this.size - a9 - a8 - a7            - a6 - a5 - a4 - a3; a2++)          {           sum = sum             .add(this.hm               .get("2n")               .multiply(                 new BigInteger(                   a2 + "")));           if (sum.compareTo(MAX) > 0)            break;           for (a1 = 0; a1 <= this.size - a9 - a8             - a7 - a6 - a5 - a4 - a3 - a2; a1++)           {            sum = sum.add(this.hm.get("1n")              .multiply(                new BigInteger(a1                  + "")));            if (sum.compareTo(MAX) > 0)             break;

           {             a0 = this.size - a9 - a8 - a7               - a6 - a5 - a4 - a3               - a2 - a1;             if (sum.compareTo(MAX) < 0               && sum.compareTo(MIN) > 0)              check(sum.toString(), a0,                a1, a2, a3, a4, a5,                a6, a7, a8, a9);            }            sum = sum.subtract(this.hm              .get("1n").multiply(                new BigInteger(a1                  + "")));           }           sum = sum             .subtract(this.hm               .get("2n")               .multiply(                 new BigInteger(                   a2 + "")));          }          sum = sum.subtract(this.hm.get("3n")            .multiply(new BigInteger(a3 + "")));         }         sum = sum.subtract(this.hm.get("4n").multiply(           new BigInteger(a4 + "")));        }        sum = sum.subtract(this.hm.get("5n").multiply(          new BigInteger(a5 + "")));       }       sum = sum.subtract(this.hm.get("6n").multiply(         new BigInteger(a6 + "")));      }      sum = sum.subtract(this.hm.get("7n").multiply(        new BigInteger(a7 + "")));     }     sum = sum.subtract(this.hm.get("8n").multiply(       new BigInteger(a8 + "")));    }    sum = sum.subtract(this.hm.get("9n").multiply(      new BigInteger(a9 + "")));   }

 }

 public static void check(String str, int a0, int a1, int a2, int a3,    int a4, int a5, int a6, int a7, int a8, int a9)//判斷0到9出現的次數是否吻合sum結果中的  {   String temp = str;   if (a0 == count(temp, "0") && a1 == count(temp, "1")     && a2 == count(temp, "2") && a3 == count(temp, "3")     && a4 == count(temp, "4") && a5 == count(temp, "5")     && a6 == count(temp, "6") && a7 == count(temp, "7")     && a8 == count(temp, "8") && a9 == count(temp, "9"))    System.out.println(str);

 }

 public static int count(String str1, String str2)//統計sum中0到9出現的次數  {   String temp1 = str1;   String temp2 = str2;   int k = -1, count = 0;   while (true)   {    k = temp1.indexOf(temp2, k + 1);    if (k != -1)     count++;    else     break;   }   return count;  }

}


 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值