POJ_1001

解题思路:

    大数乘法,将输入浮点数转化为整数,记录小数点位置,等乘法计算完毕后再添加小数点。

    这道题有较多的细节需要注意,例如,结果的整数部分若为0,则不保留整数部分。小数部分若为0,则不保留小数部分和小数点。

优化思路:(代码没有使用)

    1. 重复平方法:R ^ n =  { R ^ (n - 1) * R, n is odd | | R ^ (n / 2) * R ^ (n / 2), n is even} .

    2. 做乘法的时候,可以把数分段,即不用字符串存储,用int存,例如存4位数字,相当于将进制从10扩大到10000,减少乘法次数。

总结:

    1. debug, 应该使用简单的测试用例,考虑各种边界情况,从程序的顶层开始,首先定位问题出现的函数。

    2. 当题目细节和边界情况较复杂时,要将各种情况进行分类讨论,有助于理清解题思路。


//132k  0ms

#include <cstdio>
#include <cstdlib>
#include <cstring>

char res[151], base[7];
int exp, dec;
bool flag;

void Reverse(char *str) {
  for (char *st = str, *end = str + strlen(str) - 1; st < end; ++st, --end)
    *st ^= *end, *end ^= *st, *st ^= *end;
  return;
}

void CountDec() {
  if (flag)
    return;
  int i;
  for (i = 0; base[i] != '.' && i < 6; ++i) {}
  dec = 5 - i;
  return;
}

void DeDot() {
  if (flag)
    return;
  int i = 0;
  while (base[i] != '.')
    ++i;
  while (i < 6) {
    base[i] = base[i + 1];
    ++i;
  }
  return;
}

void Multiply() {
  int ans[151];
  memset(ans, 0, sizeof(ans));
  int i, j, k;
  for (i = 0; base[i]; ++i) {
    for (j = 0; res[j]; ++j)
      ans[i + j] += (base[i] - '0') * (res[j] - '0');
  }
  for (k = 0; k <= i + j - 1; ++k) {
    ans[k + 1] += ans[k] / 10;
    ans[k] %= 10;
  }
  for (i = 0; i <= k; ++i)
    res[i] = ans[i] + '0';
  res[i] = '\0';
  return;
}

void ReDot() {
  if (flag)
    return;
  int i, cnt;
  for (i = strlen(res), cnt = dec * exp + 1; cnt; --cnt, --i)
    res[i + 1] = res[i];
  res[++i] = '.';
  return;
}

void Trim() {
  int i;
  for (i = 0; res[i] == '0'; ++i) {}
  strcpy(res, res + i);
  for (i = strlen(res) - 1; res[i] == '0'; --i);
  if (res[i] == '.')
    res[i] = '\0';
  else
    res[++i] = '\0';
  return;
}

bool HandleZero() {
  int i;
  for (i = 0; i < 6 && (base[i] == '0' || base[i] == '.'); ++i) {}
  if (i == 6) {
    printf("0\n");
    return true;
  } else {
    return false;
  }
}

bool IsInt() {
  int i;
  for (i = 0; i < 6 && base[i] != '.'; ++i) {} 
  if (i == 6)
    return true;
  return false;
} 
int main() {
  while (scanf("%s %d", base, &exp) != EOF) {
    if (HandleZero())
      continue;
    flag = IsInt();
    CountDec();
    Reverse(base);
    DeDot();
    memset(res, 0, 151);
    strcpy(res, base);
    for (int i = 0; i < exp - 1; ++i) {
      Multiply();
    }
    Reverse(res);
    ReDot();
    Trim();
    printf("%s\n", res);
  }
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值