AOAPC I: Beginning Algorithm Contests (Rujia Liu) :: Volume 1. Elementary Problem Solving :: Big Number
// 748 - Exponentiation
// bug:底数R必须带小数点,否则运算结果不对
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#define MAXN 10000
using namespace std;
char R[MAXN];
int a[MAXN], b[MAXN], c[MAXN];
int lenR, lenA, lenB, lenC;
int i, j, _i, _j, k, m, n, p, t, _t, carry, pos, flag1, flag2;
void func() // 数组a“乘以”数组b,结果保存在数组c
{
_t = 0;
for(i=0; i<=lenA; i++)
{
carry = 0;
t = _t;
for(j=0; j<=lenB; j++)
{
carry += a[i] * b[j];
c[t] += carry % 10;
carry /= 10;
if(c[t] > 9) // 容易忽略!
{
carry += c[t] / 10;
c[t] %= 10;
}
t++;
}
_t++;
}
}
int main(void)
{
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
while(cin >> R >> n)
{
if(n==0 || atof(R)==0) // 特殊情况提前“过滤”
{
cout << 0 << endl;
continue;
}
lenR = strlen(R);
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
for(i=lenR-1; i>=0; i--)
if(R[i] != '0') // 忽略小数点后多余的零
break;
lenA = i;
for(j=i, k=0; j>=0; j--)
if(R[j] != '.')
{
a[k] = R[j] - '0';
c[k] = R[j] - '0';
k++;
} // 字符串转化为整型数组
else // 找到小数点位数
pos = lenA - j;
pos *= n; // “扩充”小数位数
for(m=0; m<n; m++) // 反复相乘
{
memset(b, 0, sizeof(b));
for(_i=MAXN-1; _i>=0; _i--)
if(c[_i] != 0) // 忽略前面的零
break;
lenB = _i+1;
for(_j=_i; _j>=0; _j--)
b[_j] = c[_j]; // 数组c复制到数组b
memset(c, 0, sizeof(c));
func();
}
for(p=0; p<MAXN; p++) // 预处理小数点后多余的零
{
if(pos==0 || p==pos)
break;
if(b[p] == 0)
b[p] = -1;
else
break;
}
for(p=MAXN-1, flag1=1, flag2=1; p>=0; p--)
{ // 令人抓狂的输出!!!
if(b[p] == -1)
break;
if(p == pos-1)
{
cout << '.';
flag1 = 0;
}
if(flag1 && flag2 && b[p]==0)
continue;
else if(flag2 && pos==0 && b[p]!=0)
{
flag2 = 0;
cout << b[p];
}
else
{
flag1 = 0;
cout << b[p];
}
}
cout << endl;
}
return 0;
}