一、目录
1.题目
2.解题遇到的问题
3.获取测试用例解决问题
4.最终答案
二、内容
1.题目
2.解题遇到的问题
解题思路:题目要求最终输出一个标准格式的两个数之和,所谓的标准格式,如下要求:
1.有负号要在最前面加‘-’号;
2.自右向左,每隔三位数就要加一个‘,’号;
3.如果最前的一组不足三位数,自左向右舍去0直到遇到一个不为0的数(有缺陷);
4.如果不是最前面的一组,需要‘,’号,且自左向右输出三个数。
由于考虑每次取余三位数(sum%1000),都是取到最后三位数,但是最开始取到的三位数却是最后输出,这让我想到了使用递归来处理该算法。
看上面的要求,我们还应该考虑正在处理的本组是不是第一组,如果是第一组(flag=0),要考虑舍去前面连续的0,如果是其他组(flag=1)则不需要考虑。
于是得到下面的算法:
#include<iostream>
#include<string>
using namespace std;
void print(int,int);
int main() {
int a, b, c;
for (; cin >> a >> b;) {
c = a + b;
if (c < 0) cout << "-";
int flag;
if (abs(c) >= 100) flag = 1;
else flag = 0;
print(abs(c),flag);
}
return 0;
}
void print(int sum,int flag) {
int end = sum % 1000;
int g, s, b;
sum = sum / 1000;
if (sum > 0&&sum<100) {
print(sum,0);
cout << ',';
}
else if (sum >= 100) {
print(sum, 1);
cout << ',';
}
g = end % 10;
s = (end / 10) % 10;
b = end / 100;
if (flag == 1) {
cout << b << s << g;
}
if (flag == 0) {
if (b != 0)cout << b << s << g;
else if (s != 0)cout << s << g;
else if (g != 0)cout << g;
}
}
但是上面的算法只能拿19分,有一个测试用例4一直测试错误,于是我想要知道测试用例到底是是什么,但是PAT不会给出测试用例,于是我用了下面的方法获取测试用例。
3.获取测试用例解决问题
a,b分别是两个整数,于是我使用二分法分别测试a,b的范围,测试方法如下:
if(a>0&&a<10000) throw a;
当a属于这个范围内时,测试用例4就会发生运行异常,而不是测试错误,通过几次的缩小范围,最终得出a=2,b=-2。
4.最终答案
原来程序的错误是当答案为0时,至少要输出一个零,所以上面的条件3应改为:
3.如果最前的一组不足三位数,自左向右舍去0直到遇到一个不为0的数,如果没有不为0的数,应该保留一个0.
最终程序为:
#include<iostream>
#include<string>
using namespace std;
void print(int,int);
int main() {
int a, b, c;
for (; cin >> a >> b;) {
c = a + b;
if (c < 0) cout << "-";
int flag;
if (abs(c) >= 100) flag = 1;
else flag = 0;
print(abs(c),flag);
}
return 0;
}
void print(int sum,int flag) {
int end = sum % 1000;
int g, s, b;
sum = sum / 1000;
if (sum > 0&&sum<100) {
print(sum,0);
cout << ',';
}
else if (sum >= 100) {
print(sum, 1);
cout << ',';
}
g = end % 10;
s = (end / 10) % 10;
b = end / 100;
if (flag == 1) {
cout << b << s << g;
}
if (flag == 0) {
if (b != 0)cout << b << s << g;
else if (s != 0)cout << s << g;
else cout << g; //需要修改的地方
}
}