您的位置:首页 > 其它

【高精度】POJ1001-Exponentiation

2015-07-03 20:37 441 查看
整个题库的第二题,原本都没有屑于去做,突发奇想抱着秒杀的心态去写了代码,却硬生生地吃了4个WA..

【思路】先去除掉小数点,进行最基本的高精度乘法运算,再在运算得到的结果中添加小数点输出。

【前铺】让我们先来看一看数组究竟需要设多大?数据范围是最大为99.999,则近似为100.000,当n=25时,至多有125个零,即最多占用125位。

【易错点】*数据1:10.000 01,如果直接从后往前去零的话,数据输出会变成1。所以删除末位多余零的范围是末位起,截止至小数点后。

     *数据2:000010 01,这个数据中根本不存在小数点!一开始我误以为6位中必然存在一位为小数点,所以将num的数组下标开为0..5,但这种情况下占用空间为0..6。我的解决方法是若当前数字存在小数点,则将其最后一位,即倒序摆放后的Num[0]设为0,整数和小数就可以统一处理了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int MAXN=125+5;
char s[MAXN];
int num[MAXN];
int ans[MAXN];
int n,ed,pos=0;

void switchnum()//将字符串转换为数字,并记录下小数点位置
{
bool have=false;
for (int i=0;i<7;i++)
{
if (s[i]=='.')
{
pos=(6-i)*n;have=true;
}
else
{
if (have) num[5-(i-1)]=s[i]-'0';
else num[5-i]=s[i]-'0';
}
}
if (have) num[0]=0;
for (int i=0;i<6;i++)
ans[i]=num[i];
}

void mul()
{
int temp[MAXN];
memset(temp,0,sizeof(temp));
for (int i=0;i<=ed;i++)
for (int j=0;j<=5;j++)
{
temp[i+j]+=ans[i]*num[j];
if (i+j>0 && temp[i+j-1]>9)
{
temp[i+j]+=temp[i+j-1]/10;
temp[i+j-1]%=10;
}
}
ed=ed+5;
if (temp[ed]>9)    //不要写成>10
{
ed++;
temp[ed]=temp[ed-1]/10;
temp[ed-1]%=10;
}
for (int i=0;i<=ed;i++) ans[i]=temp[i];
}

void output()
{
bool f=false;
int op=0;
for (int i=0;i<pos;i++)    //整数部分末位的零不能删去
{
if (ans[i]>0) break;
op++;
}
for (int i=ed;i>=op;i--)
{
if (i==pos-1)         //这里不能写成(i=pos-1)否则赋值,不要写成(i==pos+1)
{
cout<<'.';
f=true;
}
if (ans[i]>0) f=true;
if (f) cout<<ans[i];
}
cout<<endl;
}

int main()
{
while (scanf("%s%d",s,&n)!=EOF)
{
ed=5;    //除去小数点外的初始末位为5
switchnum();
for (int i=1;i<n;i++) mul();
output();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: