给出WA的简单算术(ARITH)
SPOJ: Simple Arithmetics (ARITH) giving WA
#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
不存在数字,则对operand1
和operand2
的所有数字进行一次循环,任务完成。
执行*
更棘手,但不是很多,您需要一些存储中间结果(例如: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;
}
}
}
}
相关文章:
- 为什么我在代码厨师的 CMPRSS 问题中得到 WA(错误答案)?
- 我已经通过了该问题的所有测试用例,甚至是Udebugg上的所有测试用例,并且仍然在UVA在线法官上获得了WA裁决
- 带地图的解决方案给了空调,unordered_map的解决方案给了WA.为什么
- 如何摆脱-wpointer语言 - arith
- 为什么我在SPOJ上为Buglife获得WA
- SPOJ GSS1 WA - Segment tree
- 当我试图提交mkbudge-spoj时获得WA
- Getting WA for SPOJ smpseq
- 给出WA的简单算术(ARITH)
- 为什么我在Codechef的褪色回文中得到一个WA,即使我在我的代码中没有发现任何错误,它对我来说工作得很好
- 3n+1 uVa gives WA
- 从Codechef长征比赛中获得ANUGCD的WA
- 在SPOJ INCSEQ -递增子序列中获取WA