HDU 1063 - Exponentiation

知识点:小数(大数)乘法

小数乘法的思想,就是把小数变成整数,乘完之后再加小数点。所以这道题的核心是:大数乘法。

#include <cstdio>
#include <cstring>

void times(char *a,char *b,char *t)    //大数乘法,a和b相乘,结果赋给t
{
    int len_a=strlen(a),len_b=strlen(b);
    int c[10]={0},d[200]={0},e[200]={0};
    for(int i=0;i<len_a;++i)
    c[i]=a[len_a-1-i]-'0';
    for(int i=0;i<len_b;++i)
    d[i]=b[len_b-1-i]-'0';
    int k;
    for(int i=0;i<len_a;++i)
    for(int j=0;j<len_b;++j)
    {
        k=i+j;
        e[k]+=c[i]*d[j];
        if(e[k]>9)
        {
            e[k+1]+=e[k]/10;
            e[k]%=10;
        }
    }
    int len_t=e[k+1] ? k+2 : k+1;
    for(int i=0;i<len_t;++i)
    t[i]=e[len_t-1-i]+'0';
    t[len_t]=0;
}

int main()
{
    char tmp[10];
    int n;
    while(scanf("%s%d",tmp,&n)!=EOF)
    {
        char r[10];

        //从这往下,是将tmp去头去尾,将小数化整数,存到r中
        int i,j=0,cnt,end;    //cnt记录小数位数,end用于去掉小数后面多于的0
        //找第一个不为0的位置,该位置只有两种可能:小数点或数字
        for(i=0;tmp[i]=='0';++i);
        if(tmp[i]=='.')
        {
            for(end=strlen(tmp)-1;tmp[end]=='0';--end);
            cnt=end-i;
            for(++i;tmp[i]=='0'&&tmp[i];++i);
            for(;i<=end;++i)
            r[j++]=tmp[i];
        }
        else
        {
            for(;tmp[i]!='.'&&tmp[i];++i)
            r[j++]=tmp[i];
            if(tmp[i]==0) cnt=0;
            else
            {
                for(end=strlen(tmp)-1;tmp[end]=='0';--end);
                cnt=end-i;
                for(++i;i<=end;++i)
                r[j++]=tmp[i];
            }
        }
        r[j]=0;

        char t[200];    //t存放最终结果
        strcpy(t,r);
        int flag=cnt;    //flag记录小数位数
        while(--n)
        {
            times(r,t,t);
            flag+=cnt;
        }
        int len_t=strlen(t);
        if(flag==0) puts(t);    //flag=0,说明结果是整数
        //flag>=len_t,说明需要在小数点后面、t 前面补0
        else if(flag>=len_t)
        {
            putchar('.');
            cnt=flag-len_t;
            while(cnt--)
            putchar('0');
            puts(t);
        }
        else    //小数点在 t 中间
        {
            flag=len_t-1-flag;
            for(i=0;t[i];i++)
            {
                putchar(t[i]);
                if(i==flag) putchar('.');
            }
            putchar('\n');
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值