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
Output
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真是个好东西哦~~