教你用JAVA计算21位花朵(水仙花)数

1 题目 

花朵数
一个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分钟内运行完毕。(这是蓝桥杯的比赛题,解法有很多种,我的解法是对http://www.lanqiao.org/webHomePage.action?detailArticlePage&articleId=364&catalogId=10&itemId=27  他们官方发布的视频的总结及自己的理解,对不爱看视屏的你或许有帮助)

参考结果:

128468643043731391252
449177399146038697307

 

2 解题思路

1.怎么表示结果?结果是一个21位的数字如果我们用int 和long 的话都是不能表示的。那我们要用BigInteger.应为它并没有语法长度限制,仅仅受限于机器的内存。

2.怎么处理算法?我们很容易想到遍历100000000000000000000----999999999999999999999

但是这样确实不行的。不要认为机器足够快就能就能计算出来。目前的微机硬件水平是不能出结果的。

不能每个数字去遍历,那么我们转换为21个位置0-9 每个数字出现的次数进行大排列。

例:

449177399146038697307 和 730744917739914603869

他们的21次方的和都是一样,这样我们就不用去管他们每个数字出现的位置。而转化对0-9 每个数字出现的次数进行排列。具体的一些小的技巧在程序中会体现出来

3 具体的代码

import java.math.BigInteger;


public class FlowerNum {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        long time=System.currentTimeMillis();//计时
        
        int n=21;
        BigInteger[] big=new BigInteger[10];//0-9的21次方
        
        
        for(int i=0;i<10;i++){
//            big[i]=BigInteger.valueOf(i).pow(n);
            big[i]=p(i);
            System.out.print(big[i]+"\r\n");
        }
        
        int[] nu =new int[10];
        
        //算法核心:21个位置0-9 每个数字出现的次数进行大排列。
        f(big,nu,0,0);
        
        time=System.currentTimeMillis()-time;
        System.out.print(time/1000+"s");//输出计算时间噎死一个程序结束的信号
    }

    //求次方
    private static BigInteger p(int i) {
        // TODO Auto-generated method stub
        //求21次方
        BigInteger big=BigInteger.ONE;
        for(int i1=0;i1<21;i1++)
        {
            big=big.multiply(BigInteger.valueOf(i));
        }
        return big;
    }

    //cur  是代表当前处理 nu 的第几位
    // use 是代表占用了多少位
    private static void f(BigInteger[] big, int[] nu, int cur, int use) {
        // TODO Auto-generated method stub
        //到了最后一位 。递归结束
        if(cur==9)
        {
            nu[9]=21-use;
            ji_suan(big,nu);
            return;
        }
        
        //对当前位置的所有肯呢过进行枚举
        for(int i=0 ;i<=21-use;i++)
        {
            nu[cur]=i;
            f(big ,nu,cur+1,use+i);
        }
    }

    private static void ji_suan(BigInteger[] big, int[] nu) {
        // TODO Auto-generated method stub
      //求和
      BigInteger big2=BigInteger.ZERO;
      for(int i=0;i<=9;i++)
          big2=big2.add(big[i].multiply(BigInteger.valueOf(nu[i])));//big[i]的出现次数和值的乘积的累加
      
      //把结果放到s这个字符串中
      String s=""+big2;
      
      //结果不足21位直接pass
      if (s.length()!=21)return;
      
      //确定每个数字出现的次数
      int[] nn2=new int[10];
      
      //搜寻在s中0-9出现的次数并存放在nn2 数组中
      for(int i=0 ;i<21;i++ ) nn2[s.charAt(i)-'0']++;//nn2[i]++;
      
      for(int i=0 ; i<=9;i++)  //比较出现的次数是不是相等
      {
          if(nu[i]!=nn2[i]) return;
      }
        System.out.print(s); 
      
    }

}

4 总结

      

本程序的解题过程就是:

定义—>计算0-9 的21次方-->枚举21个位置0-9出现的次数-->计算21个位置元素21次方的和-->比较和与原数的0-9出现次数比较-->输出

 

转载于:https://www.cnblogs.com/cbread/archive/2013/04/29/3050990.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 水仙花数是指一个三,它的各字的立方和等于其本身。例如,153是一个水仙花数,因为153=1^3+5^3+3^3。 下面是用 Java 来写一个计算 N 水仙花数的程序的代码示例: ``` public class NarcissisticNumber { public static void main(String[] args) { int n = 3; // N 水仙花数,这里设置为 3 for (int i = 100; i < 1000; i++) { // 因为是 3 ,所以从 100 到 999 枚举 int a = i / 100; // 得到百上的字 int b = (i / 10) % 10; // 得到十上的字 int c = i % 10; // 得到个上的字 if (a*a*a + b*b*b + c*c*c == i) { // 如果是水仙花数,输出 System.out.println(i); } } } } ``` 这段代码会枚举从 100 到 999 的字,判断是否是 N 水仙花数,如果是就输出。 希望这个示例能帮到你! ### 回答2: 水仙花数是指一个N(N≥3),其各字的N次方之和等于该本身。下面是用Java编写的一个计算N水仙花数的程序: ```java import java.util.Scanner; public class NarcissisticNumber { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入N:"); int n = scanner.nextInt(); scanner.close(); int start = (int) Math.pow(10, n-1); // 起始,如3的起始是100 int end = (int) Math.pow(10, n) - 1; // 终止,如3的终止是999 System.out.println(n + "水仙花数有:"); for (int i = start; i <= end; i++) { if (isNarcissisticNumber(i, n)) { System.out.println(i); } } } // 判断一个是否为N水仙花数 public static boolean isNarcissisticNumber(int num, int n) { int sum = 0; int temp = num; while (temp > 0) { int digit = temp % 10; // 获取当前字 sum += Math.pow(digit, n); // 求和 temp /= 10; // 去掉最低 } return num == sum; } } ``` 用户输入N后,程序会计算出N水仙花数的范围,然后逐个判断这些是否为水仙花数,并输出结果。 ### 回答3: 水仙花数是指一个N,其每个上的字的N次幂之和等于原本身。现在我来编写一个用Java语言实现计算N水仙花数的程序。 首先,我们需要用户输入NN。接下来,我们定义一个循环从10的N-1次方开始,一直到10的N次方-1。循环中,我们取当前循环变量的每个上的字,进行N次幂运算并求和。然后,我们将计算出的和与当前循环变量进行比较,如果相等则输出该。 下面是Java代码的实现: ```java import java.util.Scanner; public class NarcissisticNumber { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入NN:"); int N = scanner.nextInt(); int start = (int) Math.pow(10, N-1); int end = (int) Math.pow(10, N) - 1; for (int i = start; i <= end; i++) { int num = i; int sum = 0; while (num != 0) { int digit = num % 10; sum += Math.pow(digit, N); num /= 10; } if (sum == i) { System.out.println(i); } } } } ``` 用户运行程序后,程序会要求输入NN。然后,程序会计算出所有N水仙花数,并将其输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值