POJ 1001

简介: 此题用最朴素的思路实现即可,需模拟加法器,乘法器,最烦人的地方是特殊情形,如末位是小数点(12.^2=144,取小数点),整数末位是0(100^2=10000),0次幂,测试用例可能超出题目中说的范围,可能包含0次幂(100.0^0=0, 0.10^1=0.1)。

此题用最朴素的思路实现即可,需模拟加法器,乘法器,最烦人的地方是特殊情形,如末位是小数点(12.^2=144,取小数点),整数末位是0(100^2=10000),0次幂,测试用例可能超出题目中说的范围,可能包含0次幂(100.0^0=0, 0.10^1=0.1)。代码

#include <iostream>
#include <string>

using namespace std;

struct RLT {
    int unit; // 本位值
    int carryBit; // 进位值
};

RLT add(char ch1, char ch2, int carryBit);
RLT multiply(char ch1, char ch2, int carryBit);
string add(string op1, string op2, int x);
string multiply(string op1, char op2);
string multiply(string op1, string op2);
string remove(string str);

int main() {

    string number;
    int n;
    while (cin >> number >> n) {
        // 记录小数点位置
        int punc = -1;
        int len = number.length();
        string multiplier = ""; // 乘数, 注意每次初始化置空
        for (int i = 0; i < len; i++) {
            if (number[i] == '.') {
                punc = len - i - 1;
                continue;
            }
            // 抽取出数字位
            multiplier += number[i];
        }

        string tmpRlt = multiplier;
        if(0==n) tmpRlt = "0";
        else {
            for(int j = 1; j < n; j++) { // 相乘次数
                tmpRlt = multiply(tmpRlt, multiplier);
            }

            // 计算小数点位置
            punc = punc*n;
            int tLen = tmpRlt.length();
            if(tLen!=punc && punc > 0) // 为整数时不必加小数点
                tmpRlt = tmpRlt.insert(tmpRlt.length()-punc, ".");

            // 注意处理末位为0的整数乘积情况
            tmpRlt = remove(tmpRlt);
        }

        cout << tmpRlt << endl;
    }

    return 1;
}

// 去除字符串前后无效零位
string remove(string str) {
    int start = -1;
    int end = -1;
    bool tag = false;
    bool tag2 = false;
    int index = -1;
    int len = str.length();
    for (int i=0; i<len; i++) {
        if (str[i]!='0' && !tag) {
            start = i;
            tag = true;
        }
        if (str[len-i-1]!='0' && !tag2) {
            end = len-i-1;
            tag2 = true;
        }
        if (str[i]=='.') index = i; // 查找小数点位置
    }
    if (index<0) { // 无小数点情况
    } else { // 处理带小数点情况
        // 处理最后一位是小数点情况, 且前面位不是0
        if ('.' == str[end] && '.'!=str[start])
            str = str.substr(start, end-start);
        else if ('.'!=str[end]) // 处理最后一位不是小数点情况, 且前面位不是0
            str = str.substr(start, end-start+1);
        else
            str = "0";
    }

    return str;
}

// 一位加法器, 返回进位值, carryBit, 上一位进位值
RLT add(char ch1, char ch2, int carryBit) {
    int sum = (ch1-48)+(ch2-48)+carryBit;
    int unit = sum%10;
    int carryBit2 = sum/10;
    RLT rlt;
    rlt.unit=unit;
    rlt.carryBit=carryBit2;

    return rlt;
}

// 一位乘法器, 返回进位值
RLT multiply(char ch1, char ch2, int carryBit) {
    int product = (ch1-48)*(ch2-48)+carryBit;
    int unit = product%10;
    int carryBit2 = product/10;
    RLT rlt;
    rlt.unit=unit;
    rlt.carryBit=carryBit2;

    return rlt;
}

// 两个数错位相加
string add(string op1, string op2, int x) {
    string rlt = "";

    for (int i = 0; i < x; i++)
        op2 += '0';

    int len1 = op1.length();
    int len2 = op2.length();

    // 两个数长度对齐
    if (len1<len2) {
        for (int i=0; i< len2-len1; i++)
            op1 = '0' + op1;
    } else {
        for (int i=0;i<len1-len2; i++)
            op2 = '0' + op2;
    }

    int carryBit = 0;
    int len = len1>len2?len1:len2;
    RLT tmp;
    for (int i=0; i<len; i++) {
        tmp = add(op1[len-i-1], op2[len-i-1], carryBit);
        carryBit = tmp.carryBit;
        rlt = char(tmp.unit+48)+rlt;
    }
    // 考虑最高位进位
    if (0!=tmp.carryBit) rlt = char(tmp.carryBit+48)+rlt;

    return rlt;
}

// 多位数乘一位数
string multiply(string op1, char op2) {
    string rlt= "";
    int unit = 0;
    int carryBit = 0; // 进位
    int len = op1.length();
    for (int k=len-1; k>=0; k--) {
        RLT tRlt = multiply(op1[k], op2, carryBit);
        unit = tRlt.unit; // 每一位乘积个位数字
        rlt = (char(unit+48)) + rlt;
        carryBit = tRlt.carryBit; // 每一位乘积十位数字
    }

    if(0!=carryBit)
        rlt = char(carryBit+48) + rlt;

    return rlt;
}

// 多位数相乘
string multiply(string op1, string op2) {
    string rlt = "0";
    int len2 = op2.length();
    for (int i=len2-1; i>-1; i--) {
        // 多位数与一位数相乘
        string tmp = multiply(op1, op2[i]);
        rlt = add(rlt, tmp, len2-i-1);
    }

    return rlt;
}


目录
相关文章
POJ 1067 取石子游戏
取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 40917   Accepted: 13826 Description 有两堆石子,数量任意,可以不同。
1086 0
|
C语言
poj 2503 查字典
Description You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language.
837 0
poj 3664
http://poj.org/problem?id=3664 进行两轮选举,第一轮选前n进入第二轮,第二轮选最高   #include #include using namespace std; struct vote { int a,b; int c; ...
705 0
POJ-1003-hangover
Description How far can you make a stack of cards overhang a table? If you have one card, you can create a maximum overhang of half a card length.
737 0
|
机器学习/深度学习
|
网络协议 网络架构
poj 2675 songs
点击打开链接poj 2675 思路:相邻交换法 分析: 1 题目要求找到一种序列使得所求的值最小 2 那么根据输入的序列我们做如下处理,设sum[i]表示播放第i首歌的和 sum[i] = f[i]*(len[1]+.
829 0