SPOJ:简单的算术(ARITH)给WA

时间:2014-08-08 17:58:20

标签: c++

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;
int bigger(int a,int b,int c)
{
    if(a>b)
    {
        if(c>a)
            return c;
        else
            return a;
    }
    else
    {
        int c1=0,c2=0,c0,b0;
        b0=b;
        c0=c;
        while(c0!=0)
        {
            c0/=10;
            c1++;
        }
        while(b0!=0)
        {
            b0/=10;
            c2++;
        }
        if(c1>c2)
            return c;
        else
            return b;
    }
}
int main()
{
    int i,n;
    cin>>n;
    for(i=0;i<n;i++)
    {
        int j,a,b,big,ans,dig,d,mult,dgit,m=0,ass;
        char ch;
        string res,str="";
        cin>>a>>ch>>b;
        if(ch=='+'||ch=='-')
        {
            if(ch=='+')
                ans=a+b;
            else if(ch=='-')
                ans=a-b;

            big=bigger(a,b,ans);
            d=big;
            dig=0;
            while(d!=0)
            {
                d/=10;
                dig++;
            }
            string abc="";
            if(ch=='+')
                abc.append("+");
            else
                abc.append("-");
            string qrt;
            ostringstream oss;
            oss<<b;
            qrt=oss.str();
            abc.append(qrt);
            cout<<setw(dig);
            cout<<a<<"\n";
            if(b==big)
                cout<<setw(dig+1);
            else
                cout<<setw(dig);
            cout<<abc;
            cout<<"\n";
            int k=0;
            if(b==big)
                k--;
            for(;k<dig;k++)
                cout<<'-';
            cout<<'\n';
            if(b==big)
                cout<<setw(dig+1);
            else
                cout<<setw(dig);
            cout<<ans;
        }

        else if(ch=='*')
        {
            ans=a*b;
            mult=b;
            big=bigger(a,b,ans);
            d=big;
            dig=0;
            while(d!=0)
            {
                d/=10;
                dig++;
            }
            if(b==big)dig++;
            cout<<setw(dig);
            cout<<a<<'\n';
            cout<<setw(0);
            string abc="";
            cout<<setw(dig);
            abc.append("*");
            string qrt;
            ostringstream oss;
            oss<<b;
            qrt=oss.str();
            abc.append(qrt);
            cout<<abc;
            cout<<'\n';
            d=bigger(a,b,a*(b%10));
            ass=0;
            while(d!=0)
            {
                d/=10;
                ass++;
            }
            if(a>b)
                for(int k=0;k<ass;k++)
                    str.append("-");
            else
                for(int k=0;k<=ass;k++)
                    str.append("-");
            cout<<setw(dig)<<str;
            cout<<'\n';
            while(mult!=0)
            {
                dgit=mult%10;
                mult/=10;
                ostringstream os;
                os<< dgit*a;
                res= os.str();
                for(int q=0;q<m;q++)
                {
                   res.append(" ");
                }
                cout<<setw(dig);
                cout<<res<<'\n';
                m++;
            }
            if(ans!=dgit*a)
            {
                for(int k=0;k<dig;k++)
                    cout<<'-';
                cout<<'\n'<<setw(dig)<<ans<<'\n';
            }

        }

    }
}

此代码提供wa但我找不到不正确的测试用例。谁能解释所需的短划线数量?也许更多的测试案例。抱歉编写错误的代码。写得匆匆。这是问题http://www.spoj.com/problems/ARITH/

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题:

  • 你正在使用int来存储表达式的数量,在问题描述中清楚地说明这是一些数字最多500位的测试用例,这种数字不能存储在任何整数或浮点类型的C ++。

这个问题之王的主要目标是提交以某种自定义方式存储数字的解决方案。例如,创建一个std::vector<unsigned char>,其中向量的每个元素都是数字的数字。

执行+-是微不足道的,就像你在papel中那样做,一个变量用于进位,另一个用于存储结果(例如:其他std::vector<unsigned char>)。可以通过操作数的容器大小(-的情况)和结果(+的情况)轻松计算破折号。当没有数字时,operand1operand2的所有数字都会循环显示0,完成作业。

执行*更棘手但不多,你需要一些存储空间用于中间结果(例如:std::vector<std::vector<unsigned char>>,一个数字存储数组)。并使用进位变量一次执行一个数字的乘积与所有其他操作数。在这种情况下,破折号的数量是结果向量的大小。

一些示例代码(使用C ++ 11在GCC 4.9.0中测试):

#include <iostream>
#include <vector>

typedef std::vector<unsigned char> digit_storage_t;

void print(const digit_storage_t& operand1, unsigned int dashes) {
    while (dashes > operand1.size()) {
        std::cout << " ";
        dashes--;
    }

    for (auto d : operand1)
        std::cout << static_cast<unsigned int>(d);
}

void print(char operation, const digit_storage_t& operand2, unsigned int dashes) {
    std::cout << operation;
    while (dashes > operand2.size()) {
        std::cout << " ";
        dashes--;
    }

    for (auto d : operand2)
        std::cout << static_cast<unsigned int>(d);
}

void print_dashes(unsigned int dashes) {
    while (dashes > 0) {
        std::cout << "=";
        dashes--;
    }
}

void add(const digit_storage_t& operand1, const digit_storage_t& operand2, digit_storage_t& result) {
    result.clear();
    result.resize(std::max(operand1.size(), operand2.size()) + 1);

    unsigned int current_digit_result_idx = result.size() - 1;
    int carry = 0;

    auto current_digit_operand1 = operand1.rbegin();
    auto current_digit_operand2 = operand2.rbegin();
    while (current_digit_operand1 != operand1.rend() ||
           current_digit_operand2 != operand2.rend()) {
        int oper1 = 0, oper2 = 0;
        if (current_digit_operand1 != operand1.rend())
            oper1 = *current_digit_operand1;
        if (current_digit_operand2 != operand2.rend())
            oper2 = *current_digit_operand2;

        result[current_digit_result_idx] = (oper1 + oper2 + carry) % 10;
        carry = (oper1 + oper2 + carry) / 10;

        current_digit_result_idx--;
        current_digit_operand1++;
        current_digit_operand2++;
    }

    if (current_digit_result_idx == 0)
        result.erase(result.begin());
}

int main() {
    unsigned int expresion_count = 0;
    std::cin >> expresion_count;
    std::string line;
    std::getline(std::cin, line);
    for (unsigned int i = 0; i < expresion_count; i++) {
        std::getline(std::cin, line);

        digit_storage_t operand1;
        digit_storage_t operand2;
        digit_storage_t* actual_operand = &operand1;
        char operation = '\0';
        for (auto c : line) {
            if (c == '+' || c == '-' || c == '*') {
                operation = c;
                actual_operand = &operand2;
            } else {
                actual_operand->push_back(c - '0');
            }
        }

        switch (operation) {
            case '+': {
                digit_storage_t result;
                add(operand1, operand2, result);

                unsigned int dashes = result.size();
                print(operand1, dashes + 1);
                std::cout << std::endl;
                print(operation, operand2, dashes);
                std::cout << std::endl;
                print_dashes(dashes + 1);
                std::cout << std::endl;
                print(result, dashes + 1);
                std::cout << std::endl;
                break;
            }
            case '-': {
                // digit_storage_t result;
                // sustract(operand1, operand2, result);
                break;
            }
            case '*': {
                // std::vector<digit_storage_t> result;
                // product(operand1, operand2, result);
                break;
            }
        }
    }
}