您的位置:首页 > 其它

算法练习-求21位数的水仙花数

2016-03-11 14:11 471 查看
问题描述:在三分钟内求出所有的21位水仙花数

直接上代码:

[code]public class 求21位数的水仙花数 {
    /**
     * @param args
     */
    public static void main(String[] args) {
        long startTime=System.currentTimeMillis();//程序开始时间
        BigInteger pw[]=new BigInteger[10];
        for(int i=0;i<pw.length;i++){
            pw[i]=p(i);//每个下标存0~9的21次方
        }
        int nn[]=new int[10];//统计各个数字的出现次数
        f(pw,nn,0,0);
        System.out.println("OK");
        long endTime=System.currentTimeMillis();//程序结束时间
        System.out.println((endTime-startTime)/1000f);
    }

    private static void f(BigInteger[] pw, int[] nn, int cur, int use) {
            if(cur==9){
            nn[9]=21-use;//将当前位置的数字的次数减去使用次数
            ji_suan(pw,nn);//判断是不是水仙花数,是的话输出
            return;
        }
        //当前位置所有可能枚举
        for(int i=0;i<21-use;i++){
            /*从第一个位置开始遍历,21-use减少遍历次数,减去已用过的位置如:
            第一次大遍历,i=0,use=0时
            第一次cur==9时,nn表中数据为:0,0,0,0,0,0,0,0,0,21
            每次递归除了第一个0不变,其他位递归,且相加为21,
            第二次大遍历,i=1,use=0时
            第一次cur==9时,nn表中数据为:1,0,0,0,0,0,0,0,0,20
            每次递归除了第一个1不变,其他位递归,且相加为20,21-use(use此时为1)
            21-use就是这个意思
            *
            */
            nn[cur]=i;//0~9出现的次数
            f(pw, nn, cur+1, use+i);//pw:每个数字的21次方,nn:每个数字出现的次数,cur:当前数字,use:当前位置数字个数已使用的次数
        }
    }

    private static void ji_suan(BigInteger[] pw, int[] nn) {
        BigInteger sum=BigInteger.ZERO;
        for(int i=0;i<10;i++){
            sum=sum.add(pw[i].multiply(BigInteger.valueOf(nn[i])));
        }
        String string=""+sum;
        if(string.length()!=21)
            return;
        //确定各数字出现多少次
        int[] nn2=new int[10];
        for(int i=0;i<21;i++){
            nn2[string.charAt(i)-'0']++;
        }
        for(int i=0;i<10;i++){
            if(nn[i]!=nn2[i])
                return;
        }
        System.out.println(string);
    }

    private static BigInteger p(int i) {
        BigInteger base=BigInteger.valueOf(i);
        return base.pow(21);
    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: