PAT (Basic Level) Practice (中文)1064 朋友数 (20 分)

PAT (Basic Level) Practice (中文)1064 朋友数 (20 分)

题目描述:

如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。例如 12351 就是朋友数,因为 1 + 2 + 3 = 5 + 1 = 6,而 6就是它们的朋友证号。给定一些整数,要求你统计一下它们中有多少个不同的朋友证号。

输入格式:

输入第一行给出正整数 N。随后一行给出 N 个正整数,数字间以空格分隔。题目保证所有数字小于 104

输出格式:

首先第一行输出给定数字中不同的朋友证号的个数;随后一行按递增顺序输出这些朋友证号,数字间隔一个空格,且行末不得有多余空格。

输入样例:
8
123 899 51 998 27 33 36 12
输出样例:
4
3 6 9 26
解题思路:

本来这一题是不想写 blog 的,奈何自己的语文水平太低,导致理解题目意思上出现了偏差,故写此做个教训。

因为题目 保证所有数字小于 104 也就是最大的数也就是 9999 ,而 9999 的数位和为 36 ,也就是说题目中最大的可能的 朋友证号 也就是 [ 0 , 36 ]

/*
	采用牺牲空间来换时间的思想,即用一个 hash 数组来表明有无对应的朋友数。输入一个数 x ,
	计算出 x 的朋友数 ,然后对应 hash 数组的元素 自增 1 (也可是 bool 类型,置其值为 true 即可)
*/
int num[40] = { 0 } ;
int change(int x){
	int sum = 0 ;
	while(x){
        sum += x % 10 ;
        x /= 10 ;
    }
	return sum ; // 返回 x 数位和
}
// 对应的输入处理
for(int i = 0 ; i < n ; i ++){
	cin >> t ;
	num[change(t)] ++ ;
}

// 然后只需要对 hash 数组遍历,找到那些值发生了变化的项,其对应的下标值就是本题中要求的 朋友证号

vector<int> ans ; // 存储所有的 朋友证号
for(int i = 0 ; i < 37 ; i++)
	if(num[i] != 0)
		ans.push_back(i);

// 接下来就是排序和输出了
cout<< ans.size() <<endl ; // 输出这一组数中,不同的 朋友证号 的个数
sort(ans.begin() , ans.end()) ; // 按照升序排列
cout<< ans[0] ; // 输出第一个元素
for(int i = 1 ; i < ans.size() ; i ++)
	cout << " " << ans[i] ;  // 输出剩下的元素
cout << endl ; // 输出行末的换行
完整代码:
#include<bits/stdc++.h>
using namespace std ;
int num[40] = { 0 } ;
int change(int x){
	int sum = 0 ;
	while(x){
        sum += x % 10 ;
        x /= 10 ;
    }
	return sum ; // 返回 x 数位和
}
int main(){
	int n , t ;
	cin >> n ;
	for(int i = 0 ;i < n ; i ++){
		cin >> t ;
		num[change(t)] ++ ;
	}
	vector<int> ans ;
	for(int i = 0 ; i < 37 ; i++){
		if(num[i] != 0)
			ans.push_back(i) ;
	}
	cout<< ans.size() <<endl ; // 输出这一组数中,不同的 朋友证号 的个数
	sort(ans.begin() , ans.end()) ; // 按照升序排列
	cout<< ans[0] ; // 输出第一个元素
	for(int i = 1 ; i < ans.size() ; i ++)
		cout << " " << ans[i] ;  // 输出剩下的元素
	cout << endl ; // 输出行末的换行
	return 0 ;
}
大佬代码:
nclude <iostream>
#include <set>
using namespace std ;
int getFriendNum(int num) {
    int sum = 0 ;
    while(num != 0) {
        sum += num % 10 ;
        num /= 10 ;
    }
    return sum ;
}
int main() {
    set<int> s ;
    int n , num ;
    scanf("%d", &n) ;
    for(int i = 0 ; i < n ; i++) {
        scanf("%d", &num) ;
        s.insert(getFriendNum(num)) ;
    }
    printf("%d\n" , s.size()) ;
    for(auto it = s.begin() ; it != s.end() ; it++) {
        if(it != s.begin()) printf(" ");
        printf("%d" , *it) ;
    }
    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lingchen0522

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值