北大1001题

 题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1001

需要考虑不少细节的高精度实数乘法运算

1,预处理:去掉小数点和相应的前导零,并记录小数点的位置

2,高精度乘法:逐步来就可以

3,结果修正:在结果中加上小数点,并且去掉末尾的0和整数部分的无效0

 

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

#define MAX 200

int main()
{
 freopen("in.txt","r",stdin);
 char op[7],res[MAX],tmp[MAX],*tt;
 int i,j,k,n,p,plen,tlen,len;

 while(cin >> op >> n)
 {
  plen = strlen(op);
  reverse(op,op+plen);
  tt = find(op,op + plen,'.');
  if(tt != op + plen)
  {
   p = tt - op;
   copy(tt+1,op+plen+1,tt);
   tt = op + plen - 2;
   while(tt != op && *tt == '0')
   {
    *tt = 0;
    --tt;
   }
  }
  else
   p = 0;

  plen = strlen(op);
  memset(res,0,sizeof(res));
  res[0] = '1';
  for(i = 0;i < n;++i)
  {
   strcpy(tmp,res);
   tlen = strlen(tmp);
   len = tlen + plen;
   for(j = 0;j < len;++j)
    res[j] = 0;

   for(j = 0;j < tlen;++j)
   {
    for(k = 0;k < plen;++k)
    {
     res[j+k] += (tmp[j] - '0') * (op[k] - '0');
     if(res[j+k] > 9)
     {
      res[j+k+1] += res[j+k] / 10;
      res[j+k] %= 10;
     }
    }
   }

   while(len > 1 && res[len-1] == 0)
    --len;

   for(j = 0;j < len;++j)
    res[j] += '0';
   res[len] = '/0';
  }
  
  p *= n;
  if(p < len)
  {
   copy_backward(res+p,res+len+1,res+len+2);
   res[p] = '.';
   ++len;
   res[len] = '/0';
  }
  else if(p == len)
  {
   res[len] = '.';
   ++len;
   res[len] = '0';
   ++len;
   res[len] = '/0';
  }
  else
  {
   fill_n(res+len,p - len,'0');
   res[p] = '.';
   ++p;
   res[p] = '0';
   ++p;
   len = p;
   res[len] = '/0';
  }
  
  tt = find(res,res + len,'.');
  if(strlen(tt) == 2 && res[len-1] == '0')
   res[--len] = '/0';

  tt = res;
  while(tt != res + len && *tt == '0')
   ++tt;

  if(tt == res + len)
  {
   res[0] = '0';
   res[1] = '/0';
  }
  else if(*tt == '.')
   copy(tt+1,res+len+1,res);
  else
   copy(tt,res+len+1,res);
  len = strlen(res);

  reverse(res,res+len);
  cout << res << endl;
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值