ACM北大的第1001题

算法一直被认为是高手才可以接触的东西,虽说大学里老师都说程序=数据结构+算法,可是在实际工作中用到算法的机会真的不多。最近突然觉得,如果要做高级的工作,比如架构师,搜索,自然语言处理,数据挖掘等等方面,算法是一个非常重要的东西,因此觉得开始练习算法,提高自己的算法能力。说到算法的话,ACM肯定是一个必知的词汇了,总觉得做ACM的人很牛,我也想成为一个牛人,虽然水平很烂。

果然,北大的第一道题目就把我难住了(A+B那题除外,那基本就是例子),题目是这样的:

Description
Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.

This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

Input
The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.

Output
The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.

Sample Input

95.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12

Sample Output

548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201

我花了时间自己从头到尾实现了整个算法:

package com.seiya;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * Created by dell on 2015/10/27.
 */
public class Exponentiation {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while(scanner.hasNext()) {
            String str = scanner.nextLine();
            if(str.equals("EOF")) break;
            //System.out.println(str);
            //long time1 = System.currentTimeMillis();
            String real = str.substring(0,str.indexOf(" ")).trim();
            //System.out.println(str);
            String n = str.substring(str.lastIndexOf(" ")).trim();
            //System.out.println("real: "+real+", n: "+n);
            String result = real;
            int nn = Integer.valueOf(n);
            if(!real.contains(".")) {
                for (int i = 1; i < nn; i++) {
                    result = multiply(result, real);
                }
            }else {
                int point = (real.length()-1)-real.indexOf('.');
                //System.out.println("point:"+point);
                real = real.replace(".","");
                //System.out.println("real:"+real);
                int rp = point*nn;
                result = real;
                for (int i = 1; i < nn; i++) {
                    result = multiply(result, real);
                }
                String r1 = result.substring(0,result.length()-rp);
                String r2 = result.substring(result.length()-rp);
                result = r1+"."+r2;
                // 去除末尾的0
                for(int i = result.length()-1;i >= 0; i--) {
                    if(result.endsWith("0")) {
                        result = result.substring(0,result.length()-1);
                    }
                }
                // 去除小数点前的0
                String prefix = result.substring(0,result.indexOf("."));
                if(prefix.equals("0")) {
                    result = result.substring(1);
                }
            }
            System.out.println(result);
            //long time2 = System.currentTimeMillis();
            //System.out.println("time: "+(time2-time1));
        }

    }

    public static String multiply(String a,String b) {
        String rstr = "";
        ArrayList<ArrayList<Integer>> tempResult = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> result = new ArrayList<Integer>();
        char[] array1 = a.toCharArray();
        char[] array2 = b.toCharArray();
        for(int i = array1.length-1; i >= 0; i--) {
            ArrayList<Integer> temp = new ArrayList<Integer>();
            for(int j = array2.length-1; j >= 0; j--) {
                int ai = Integer.parseInt(""+array1[i]);
                int bj = Integer.parseInt(""+array2[j]);

                temp.add(ai*bj);
            }
            for(int k=0;k<temp.size()-1;k++) {
                int c = temp.get(k);
                if(c>=10) {
                    int d = temp.get(k+1);
                    d += c/10;
                    temp.set(k+1,d);
                    c=c%10;
                    temp.set(k,c);
                }
            }
            tempResult.add(temp);
        }

        result = tempResult.get(0);
        for(int i = 0; i < tempResult.size()-1; i++) {
            result = myadd2(result, tempResult.get(i + 1), i + 1);
        }

        for(int i = result.size()-1; i >= 0; i--) {
            rstr += result.get(i);
        }
        return rstr;
    }

    public static ArrayList<Integer> myadd2(ArrayList<Integer> a,ArrayList<Integer> b,int k) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        for(int i = 0;i < k;i++) {
            result.add(a.get(i));
        }

        for(int i = k; i < a.size(); i++) {
            int temp = a.get(i)+b.get(i-k);
            if(temp>=10) {
                result.add(temp % 10);
                b.set(i-k+1,b.get(i-k+1)+temp/10);
            }else {
                result.add(temp);
            }
        }
        result.add(b.get(b.size()-1));
        return result;
    }
}

总体上思路是这样的:先实现一个大数相乘的乘法运算,然后把幂运算看做是很多个大数相乘,根据小数点的位数,再决定该把小数点放在哪里,然后去除多余的0。在实现大整数乘法的运算时,先实现各个数字相乘,并把结果暂存在一个ArrayList中,然后取出结果并错位相加,就得到乘法的结果。

感觉上应该是没有问题的,事实上我经过测试结果都是正确无误的,不过在北大的ACM算法提交的时候就报错了,话说我也不知道为什么错了,错在哪里,等我以后水平更高再来看吧。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值