给出WA的简单算术(ARITH)

SPOJ: Simple Arithmetics (ARITH) giving WA

本文关键字:ARITH WA 简单 给出      更新时间:2023-10-16
#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/

你的代码有一些问题:

  • 你正在使用int来存储表达式的数字,在问题描述中明确指出,这将是一些测试用例的数字高达500位,这种数字不能存储在任何整数或浮点类型的c++。

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

执行+-是微不足道的,就像你在纸上做的那样,一个变量用于进位,另一个用于存储结果(例如:其他std::vector<unsigned char>)。破折号可以很容易地通过操作数容器的大小(-的情况)和结果(+的情况)来计算。假设0不存在数字,则对operand1operand2的所有数字进行一次循环,任务完成。

执行*更棘手,但不是很多,您需要一些存储中间结果(例如:std::vector<std::vector<unsigned char>>,一个数字存储数组)。并使用进位变量,每次与纸上的所有其他操作数进行一个数字的乘积。在本例中,破折号的计数就是结果向量的大小。

一些示例代码(在GCC 4.9.0和c++ 11中测试):

#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 = '';
        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;
            }
        }
    }
}