poj 1001 Exponentiation 模仿大数(hdu 1063)
发布时间:2021-05-26 06:31:32 所属栏目:大数据 来源:网络整理
导读:poj 1001 Exponentiation ? 模仿 大数 链接: http://poj.org/problem?id=1001 题意: 题意很简朴,给你2个数(前面的是小数,后头是不高出25的整数),求得前一个数的幂(后一个数作指数部门)。 思绪: 要求小数的幂,用一样平常的double,float完全满意不相识
poj 1001 Exponentiation ?模仿大数链接: http://poj.org/problem?id=1001题意:题意很简朴,给你2个数(前面的是小数,后头是不高出25的整数),求得前一个数的幂(后一个数作指数部门)。思绪:要求小数的幂,用一样平常的double,float完全满意不相识的需求。并且看到案例就知道必定用大数办理。 大数办理最简朴的看来是用JAVA直接可以求,不外我还没有进修JAVA,只能悲催的用字符串来办理。 因为第2个数(指数项)并不大,完全可以以相乘来办理乘方。 又因为小数点可以自行推算,以是可以把小数做整数来求,最后再插入小数点。 以是,我们总结起来要办理的题目,无非下面几点: 1.怎样做整数乘法,并记录大数? 大数乘法,原来必要俩个乘数都化为字符串情势,逐位相乘,再进位记录。但这一题乘数只有5位酱紫,可以用整数记录。 那么只必要一个用数组记录功效,另一个用整数记录。 2.怎样找到小数点位置? 小数就为原本查找到小数距最后一位的间隔乘上指数就是最后小数点距最后一位的间隔。 3.怎样做最后输出(舍去前导0和后导0) 探求到有效的开始下标数,和竣事下标数。 ac代码:#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <string> #include <algorithm> using namespace std; #define ll long long #define PI acos(-1.0) const int INF=99999999; const int MAXN=3000; const int mod=100; int result[130]; //记录功效数组 int multiplier; //作乘数 void multiply() { int temp[130]; //进程数组 memset(temp,sizeof(temp)); for(int i = 0; i < 130; i++) { int t = result[i] * multiplier; int carry = (t + temp[i]) / 10; //必要进位的数 temp[i] = (t + temp[i]) % 10; //不必要进位的数 //进位处理赏罚 int g = 1; while(carry) { int t = temp[i+g] + carry; carry = t / 10; temp[i+g] = t % 10; g++; } } //传回数组数值 for(int i = 0; i < 130; i++) result[i] = temp[i]; } void output(int point) { int began=0,aim=129; for(int i = 0; i < 130 ;i++) { began = i; if(i == point) break; if(result[i] != 0) break; } for(int i = 129; i >= 0; i--) { aim = i; if(result[i] != 0) break; if(i == point-1) break; } for(int i = aim; i >= began; i--) { if(i == point-1) cout << '.'; cout << result[i]; } cout << endl; } int main() { char a[15]; int n; while(~scanf("%s%d",a,&n)) { memset(result,sizeof(result)); //初始化 int point; //记录小数点位置 int index=4; //记录下标 multiplier = 0; //处理赏罚乘数的值,点的位置,功效数组的初始值 for(int i=0;i<6;i++) { if(a[i] == '.') point = i; else { multiplier = multiplier*10+(a[i]-'0'); result[index--] = a[i]-'0'; } } //处理赏罚最终点的位置 point = 5 - point; point = point * n; //连乘 for(int i = 1; i < n; i++) multiply(); //for(int i=0;i<= 50;i++) //cout << result [i]; //cout << endl; output(point); } return 0; }发明以上代码在HDU1063并过不了。 此刻从头编写了一份代码,已AC: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> using namespace std; const int N = 130; int result[N]; char real[N]; char s[10]; int main() { int n; while(~scanf("%s",s)) { memset(result,sizeof(result)); scanf("%d",&n); int temp[N]; int len = strlen(s); int point_id = -1; //小数点后头数字的数目 int k = 0; int a = 0,b = 1; for(int i = len-1; i >= 0; i--) { if(s[i] != '.') { result[k++] = s[i]-'0'; a += (s[i]-'0')*b; b *= 10; } else point_id = k; } if(point_id != -1) point_id = point_id*n; printf("%dn",point_id); n--; while(n--) { memset(temp,sizeof(temp)); int add = 0; for(int i = 0; i < N; i++) { int x = a*result[i]; printf("%d xn",x); int g = 0; while(x) { int f = temp[i+g]+x; x = f/10; temp[i+g] = f%10; g++; } } for(int i = 0; i < N; i++) result[i] = temp[i]; } k = 0; int flag = 0; for(int i = 0; i < N; i++) { if(i == point_id) { real[k++] = '.'; point_id = -1; flag = 1; } if(result[i] == 0 && point_id != -1 && !flag) continue; real[k++] = result[i]+'0'; flag = 1; } real[k] = ' '; puts(real); flag = 0; for(int i = k-1; i >= 0; i--) { if(i == 0 && real[i] == '.') continue; if(real[i] != '0') { printf("%c",real[i]); if(flag == 0) flag = 1; } else if(flag == 1 && real[i] == '0') printf("%c",real[i]); } puts(""); } return 0; } (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |