题目描述
如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。例如 123 和 51 就是朋友数,因为 1+2+3 = 5+1 = 6,而 6 就是它们的朋友证号。给定一些整数,要求你统计一下它们中有多少个不同的朋友证号。
输入格式:
输入第一行给出正整数 N。随后一行给出 N 个正整数,数字间以空格分隔。题目保证所有数字小于 104。
输出格式:
首先第一行输出给定数字中不同的朋友证号的个数;随后一行按递增顺序输出这些朋友证号,数字间隔一个空格,且行末不得有多余空格。
输入样例:
8
123 899 51 998 27 33 36 12
输出样例:
4
3 6 9 26
问题分析
流程:输入数并把本次输入的各位数和求出来、然后去保存结果的数组里看它有没有出现过,出现过就不再加入输出结果的数组,没出现过就加入输出数组、最后做递增排序,按格式输出。
以下是处理的细节:
- 每次输入的各位数字的求和:用 tmp 对 10 取余并把余数加到临时变量 tmpsum 上(这个变量每次循环的开始都会初始化为0),然后tmp /= 10。重复此步骤直到 tmp 为 0;
- 查这次的各位数字之和 tmpsum 是否出现过:用 vector 的 iterator 加 algorithm 中的 find 函数。如果没出现过,那么加入到待输出的数组中。这样做保证待输出的数组中的元素不会重复;
- 排序 + 输出:sort 方法默认递增排序;输出第一行是朋友数个数,即结果数组长度,换行;第二行保证行末不要有空格的方法,我一般都是将最后一个数字的输出格式和前几个数字的输出做分别处理。这点很简单,在代码里了,我不重复了。PAT遇到行末尾不允许空格的我基本都是这样处理的。
代码
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
int n, tmp, tmpsum;
std::vector<int> nums;
std::vector<int>::iterator it;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &tmp);
tmpsum = 0;
while (tmp != 0) {
tmpsum += tmp % 10;
tmp /= 10;
}
it = find(nums.begin(), nums.end(), tmpsum);
if (it == nums.end()) nums.push_back(tmpsum);
}
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
if (i == 0) std::cout << nums.size() << std::endl;
if (i != nums.size() - 1) std::cout << nums[i] << " ";
if (i == nums.size() - 1) std::cout << nums[i];
}
return 0;
}
疑惑
我认为这个题目还是不够严谨,各位数字之和只出现过一次这种情况算不算朋友数?题目没有说,我写的时候也没有想过。按自己写的代码,默认只要没出现过就算了,然后输出。在线判题也是这样。但我觉得针对这种情况应该说明。