poj1001解题报告
这一道题在poj上的AC ratio很低,客观上是因为这道题的细节较多,特别是在输出格式上的细节。在discuss中,我看到有一些人贴出代码,这个做法我不赞同,不管怎么 样,如果只是不加深入研究的复制粘贴AC,那也没有任何意义。给出一些测试数据帮助思考,我还是比较赞同的。
算法是一个半数学半工程的学科,所以它首先是严谨的,另外它又有别于数学更加贴近实际的问题。算法解决问题,不单纯依赖数学,生活实际中的问题有一些更注重策略和解决方案,而非数学。
希望以上的代码和叙述能给后来者一些有用的提示,切忌直接拷贝代码哦,如果能帮到你,我会很惊喜。
#include <cstdio> #include <vector> #include <cstring> using namespace std; struct BigNumber { BigNumber() { body.clear(); dot = 0; } vector<int> body; int dot; }; void display(BigNumber b) { int len = b.body.size(); //去掉大整数的前导零 int rid = len -1; while(b.body[rid] == 0) { rid--; } len = rid + 1; int dot = b.dot; if(dot == 0)//如果没有小数部分,则直接输出 { int i; for(i=len-1;i>=0;i--) printf("%d", b.body[i]); printf("\n"); } else { if(dot <= len) { //get rid of trailing zeros int i = 0; while(b.body[i] == 0 && i<= dot-1) { i++; } int j; for(j=len-1;j>=i;j--) { if(j+1 == dot) printf("."); printf("%d", b.body[j]); } printf("\n"); } else { int i=0; while(b.body[i] == 0 && i <= dot-1) { i++; } int delta = dot - len; printf("."); while(delta>0) { printf("0"); delta--; } int j; for(j=len-1;j>=i;j--) printf("%d", b.body[j]); printf("\n"); } } } //大数乘法需要保证无前导零 BigNumber multi(BigNumber sa, BigNumber sb) { int lena = sa.body.size(); int lenb = sb.body.size(); BigNumber ret; int i, j; for(i=0;i<lena;++i) { for(j=0;j<lenb;++j) { int item = sa.body[i] * sb.body[j]; // put item into ret's (i+j)th space while(i+j>=ret.body.size()) { ret.body.push_back(0); } //for ret, here char is used as int,这里使用char来存每一位,不知道会不会溢出? ret.body[i+j] += item; } } ret.dot = sa.dot + sb.dot; //do shifting on ret int k; for(k=0;k<ret.body.size();++k) { if(ret.body[k]>=10) { if(k+1==ret.body.size()) ret.body.push_back(0); ret.body[k+1] += ret.body[k] / 10; ret.body[k] = ret.body[k] % 10; } } return ret; } BigNumber solve(BigNumber s, int n) { if(n == 1) return s; if(n%2 == 0) { BigNumber b = solve(s, n/2); return multi(b, b); } else { BigNumber c = solve(s, (n-1)/2); BigNumber d = multi(c, c); return multi(d, s); } }
char s[10]; int n; int main() { while(scanf("%s%d", s, &n) == 2) { struct BigNumber ini; int len = strlen(s); int i; for(i=len-1;i>=0;i--) { if(s[i] == '.')// here, i == len -1 is impossible ini.dot = len-1 - i; else ini.body.push_back(s[i]-'0'); } BigNumber res = solve(ini, n); display(res); } return 0; }