POJ 1001

第一次刷OJ,本想着做题简单的找找信心,结果被悲催地恶心到了,开始没想这么周全,导致后期到处打补丁,代码实在是惨不忍睹了,更悲剧的是依然是Wrong Answer,真心要哭了都!当时想的很好,每一道题都要自己想,不许看别人的代码,哎,现在第一题就破戒了,题中示例的input都能得到正确的output,就是不知道它测试时到底用了什么诡异的数字,想多试几次,可OJ都是504 Gateway Time-out了,太郁闷了,只好网上寻求解答。心情真的很down啊。。废话说了太多,进入正题。

主要是以下几个网址给了我莫大的帮助,对这些PO主们表示衷心的感谢!

http://wenku.baidu.com/view/54adf6c18bd63186bcebbc68.html 高精度运算的各种扩展

http://www.cnblogs.com/HCOONa/archive/2010/07/10/1775005.html 有测试数据下载

http://www.cnblogs.com/jackes/archive/2012/03/31/2426999.html 代码中一些细节处理得很好

题目 POJ 1001

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

贴个自己写的,有点乱,好多补丁ORZ

#include<stdio.h>
#include<string.h>

int multi(int a[], int b[], int c[], int aLength, int bLength)
{
    int i, j;
    for(i=0; i<aLength; i++)
    {
        for(j=0; j<bLength; j++)
        {
            c[i+j] += a[i]*b[j];
            if(c[i+j] > 9)
            {
                c[i+j+1] += c[i+j]/10;
                c[i+j] %= 10;
            }
        }
    }
        return aLength+bLength;
}

void main()
{
    char s[150];//整数部分3*25,小数部分3*25,共150
    char result[150];
    int n,i,j,digitLength,floatLength,alen,blen,clen,zeroFlag;
    int a[150],b[150],c[150]={0};
    char temp;
    while(scanf("%s%d",s,&n) == 2)
    {
        zeroFlag = 1;
        for(i=0; i<strlen(s); i++)
            if(s[i] != '0' && s[i] != '.')
                zeroFlag = 0;
        if(zeroFlag == 1)
            printf("0\n");
        else if(n == 0)
            printf("1\n");
        else
        {
            //去掉小数点,即小数点右移floatLength位
            digitLength = strlen(s);
            floatLength = 0;
            for(i=0; i<digitLength; i++)
            {
                if(s[i] == '.')
                {
                    floatLength = digitLength-(i+1);
                    for(; i<digitLength-1; i++)
                        s[i] = s[i+1];
                    s[i] = '\0';
                    digitLength--;
                    break;
                }
            }    
            //反转
            for(i=0; i<digitLength/2; i++)
            {
                temp = s[i];
                s[i] = s[digitLength-1-i];
                s[digitLength-1-i] = temp;
            }
            
            //换成int型
            for(i=0; i<digitLength; i++)
            {
                a[i] = s[i] - '0';
                b[i] = a[i];
            }
            alen = digitLength;
            blen = digitLength;
            //做乘法
            for(i=1; i<n; i++)
            {        
                clen = multi(a, b, c, alen, blen);
                alen = clen;
                for(j=0; j<clen; j++)
                {
                    a[j] = c[j];
                    c[j] = 0;
                }
            }
            //输出
            floatLength *= n;
            //去掉前面的0
            j=alen-1;
            while(a[j]==0 && j>=floatLength)
                j--;
            for(i=j; i>=floatLength; i--)
                    printf("%d", a[i]);
            if(floatLength > 0)
            {
                //去掉后面的0
                j=0;
                while(a[j]==0)
                    j++;
                if( i>=j)
                    printf(".");
                for(; i>=j; i--)
                    printf("%d", a[i]);
            }
            printf("\n");
            
        }
        
    }
}

看到AC简直热泪盈眶!!!主要对0的处理上好烦,不看测试数据集肯定挂了

================================================

后来发现有个用JAVA写的,超级超级简单 http://blog.sina.com.cn/s/blog_6635898a0100ov2f.html

import java.io.*;
import java.math.*;
import java.util.*;
import java.text.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        BigDecimal num;
        int ep, sta, end, i;
        String st;
        while(cin.hasNext()){                      //  相当于c++的!=EOF。
            num = cin.nextBigDecimal();
            ep = cin.nextInt();
            num = num.pow(ep);                     //  计算num^ep。
            st = new String(num.toPlainString());  //  toString()会有科学记数法。
            sta = 0;
            while(st.charAt(sta) == '0') sta ++;   //  去掉前缀的0。
            end = st.length() - 1;
            while(st.charAt(end) == '0') end --;   //  去掉后缀的0。
            if(st.charAt(end) == '.') end --;      //  若小数点后没0,去掉小数点。
            for(i = sta; i <= end; i ++)
                System.out.print(st.charAt(i));
            System.out.println();
        }
        System.exit(0);
    }
}

这样看来BigDecimal真是个好东西哦~~

posted @ 2013-04-22 15:03  sillypudding  阅读(1363)  评论(0编辑  收藏  举报