版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25203255/article/details/78847023
1 问题描述
Description
对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。Input
T输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。
Output
对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。
Sample Input
95.123 12
0.4321 20
5.1234 15
6.7592 9
98.999 10
1.0100 12
题目地址 poj 1001
2 算法实现
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 进位调整
void carry_bit(vector<int>& n) {
// 从后向前进行进位, 默认进位值C=0
int i, C = 0;
for(i = n.size() - 1; i >= 0; -- i) {
int v = n[i] + C;
n[i] = v % 10;
C = v / 10;
// 第一位也需要进位的情况
if(C && !i) n.insert(n.begin(), C);
}
}
// n1 乘数 n2 被乘数
vector<int> mul(const vector<int>& n1, const vector<int>& n2) {
vector<int> result;
int i, j;
// n1每位数从前向后(简化调位操作)和n2相乘
for(i = 0; i < n1.size(); ++ i) {
vector<int> t;
for(j = 0; j < n2.size(); ++ j)
t.push_back(n2[j] * n1[i]);
// 如果i = 0直接复制到result中
if(i == 0) result = t;
else {
// 先调位
carry_bit(t);
// 错位相加,最后1为无数可加,直接复制到最后面
int k = t.size() - 1;
result.push_back(t[k--]);
// 剩余的数和部分积相加
for(j = result.size() - 2; j >=0 && k >=0 ; -- j, -- k)
result[j] += t[k];
}
// 对部分积调位
carry_bit(result);
}
return result;
}
// 去掉前导的 0 后不要的 0
int toList(string& s, vector<int>& out) {
int dot = 0, i;
// 去掉最前面的0
for(i = 0; i < s.size() && s.size() != 1; ) {
if(s[i] != '0' || (s[i] == '0' && s[i + 1] == '.')) break;
if(s[i] == '0') s.erase(i, 1);
}
// 如果存在小数点,去掉最后面的0
for(i = s.size() - 1; i >= 0 && s.find('.'); ) {
if(s[i] == '.') {
s.erase(i, 1);
break;
}
else if(s[i] == '0') s.erase(i --, 1);
else break;
}
// 分割每一个数字,不使用小数点参与运算
for(i = 0; i < s.size(); ++ i) {
if(s[i] == '.') dot = i;
else out.push_back(s[i]-'0');
}
return dot;
}
int main()
{
string s;
int n;
while(cin>>s>>n) {
vector<int> v;
int i, k, d = toList(s, v);
vector<int> result = v;
for(i = 1; i < n; ++ i)
result = mul(v, result);
// 计算小数点位置
k = result.size() - (v.size() - d) * n - 1;
// 乘数为0的情况
if(result.empty()) cout << "0";
for(i = 0; i < result.size(); ++ i) {
if(d) {
// 第一位是0同时紧跟小数点的情况=> .xxxx
if(!(!k && !result[i] && !i)) cout << result[i];
if(i == k) cout << ".";
}
// 无小数点的情况
else cout << result[i];
}
cout << endl;
}
return 0;
}