【题目链接】
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;
}