信息学奥赛一本通 1184 | 1934:【06NOIP普及组】明明的随机数 | OpenJudge NOI 1.10 09 | 洛谷 P1059 [NOIP2006 普及组] 明明的随机数

【题目链接】

ybt 1184:明明的随机数
ybt 1934:【06NOIP普及组】明明的随机数
OpenJudge NOI 1.10 09:明明的随机数
洛谷 P1059 [NOIP2006 普及组] 明明的随机数

【题目考点】

1. 计数排序

【君义精讲】排序算法

2. STL set

set底层原理是红黑树。set可以表示集合,集合中相同的数值只能保留一个。

【解题思路】

解法1:计数排序

计数排序模板题
设vis数组,长度为数字的范围(1000),vis[i]为true表示数字i已经出现过。由于要做去重,所以只需要记录一个数字是否出现过。
把输入的每个字在vis数组中做标记,而后遍历vis数组,计数vis[i]为true的元素个数。再遍历vis数组,如果vis[i]为true,输出i。
也可以在遍历时,将vis[i]为真的i加入一个vector中,最后输出。

解法2:使用STL set

设容器set,每输入一个数字就插入set。如果有重复的数字插入set,set中只会保存一份。最后输出set中元素的个数,和其中每个元素的值。
由于set底层原理是红黑树,用迭代器遍历set,实际就是对红黑树做中序遍历,输出的就是升序序列。

【题解代码】

解法1:计数排序
  • 写法1:遍历vis数组输出
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n, a, ct = 0;//ct:数字个数
	cin >> n;
	bool vis[1005] = {};//vis[i]:是否存在数字i 初值设为false
	for(int i = 1; i <= n; ++i)
	{
		cin >> a;
		vis[a] = true;
	}
	for(int i = 1; i <= 1000; ++i)
	{
		if(vis[i])
			ct++; 
	}
	cout << ct << endl;
	for(int i = 1; i <= 1000; ++i)
	{
		if(vis[i])
			cout << i << ' ';
	}
	return 0;
}
  • 写法2:计数排序 使用vector记录要输出的数字,而后输出
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n, a, ct = 0;
	vector<int> vec;
	cin >> n;
	bool vis[1005] = {};//vis[i]:是否存在数字i 
	for(int i = 1; i <= n; ++i)
	{
		cin >> a;
		vis[a] = true;
	}
	for(int i = 1; i <= 1000; ++i)
	{
		if(vis[i])
		{
			ct++;
			vec.push_back(i);
		}
	}
	cout << ct << endl;
	for(int i = 0; i < vec.size(); ++i)
		cout << vec[i] << ' ';
	return 0;
}
解法2:使用STL set
  • 写法1:迭代器遍历
#include <bits/stdc++.h>
using namespace std;
int main()
{
	set<int> st;
	int n, a;
	cin >> n;
	for(int i = 1; i <= n; ++i)
	{
		cin >> a;
		st.insert(a);
	}
	cout << st.size() << endl;
	for(set<int>::iterator it = st.begin(); it != st.end(); ++it)
		cout << *it << ' ';
	return 0;
}
  • 写法2:for冒号遍历
#include <bits/stdc++.h>
using namespace std;
int main()
{
	set<int> st;
	int n, a;
	cin >> n;
	for(int i = 1; i <= n; ++i)
	{
		cin >> a;
		st.insert(a);
	}
	cout << st.size() << endl;
	for(int v : st)
		cout << v << ' ';
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值