欢迎光临
我们一直在努力

去重排序c++(绝非正解)

对于又要排序又要去重的基础题。比如

P1059 [NOIP 2006 普及组] 明明的随机数

题目描述

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 NNN111100010001000 之间的随机整数 (N≤100)(N\\leq100)(N100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

输入格式

输入有两行,第 111 行为 111 个正整数,表示所生成的随机数的个数 NNN

222 行有 NNN 个用空格隔开的正整数,为所产生的随机数。

输出格式

输出也是两行,第 111 行为 111 个正整数 MMM,表示不相同的随机数的个数。

222 行为 MMM 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

输入输出样例 #1

输入 #1

10
20 40 32 67 40 20 89 300 400 15

输出 #1

8
15 20 32 40 67 89 300 400

说明/提示

NOIP 2006 普及组 第一题


这道题不难,代码也很短,但本人写起来觉得它很烦。为啥呢?因为用 sort 的话去重很烦(unique太难拼了,没学过的忽略这一句),手动排序——呃,谁学了 sort 之后还用手动排啊。

于是就这样,这道题很烦,归根结底,原因还是在于太老掉牙了(这种题没做过十次也有八次了)于是我今天分享一个新奇的方法。


首先,众所周知,c++里有一个STL容器叫 set(集合)。
以下是它的自带函数:

函数作用
s.insert(val) 插入元素 val;重复元素直接忽略
s.size() 返回集合中元素个数(去重后的数量)
s.empty() 集合为空返回 true,否则 false
s.clear() 清空所有元素
s.find(val) 查找 val,返回迭代器;找到→指向该元素;找不到→s.end()
s.erase(val) 删除值为 val 的所有元素
s.erase(迭代器) 删除迭代器指向的单个元素
s.begin() 迭代器,指向最小元素(第一个)
s.end() 尾后迭代器,不指向有效元素,遍历终止条件

核心特性

自动有序:

容器内部使用红黑树(平衡二叉搜索树)存储元素,默认从小到大升序排列

元素唯一(自动去重):

不能存

放重复值;
插入相同元素不会报错,但是插入无效

不支持随机访问:

不能用 s[0]、s[1] 下标取值,只能依靠迭代器遍历
迭代器双向遍历,只能 ++it、–it


简单来说就是这个东西可以自动排序去重,简直就是专门为这道题设计的。所以我们要做的就是: 输入 -> 输出。

#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
set<int> s;
for (int i = 1; i <= n; ++i){
int x;
cin >> x;
s.insert(x);
}
cout << s.size() << endl;
for (auto it = s.begin(); it != s.end(); ++it)
cout << *it<<" ";
cout << endl;
return 0;
}

for (auto it = s.begin(); it != s.end(); ++it) 这个是用迭代器遍历,没学过的就把这一句背下来并知道 set 只能用这个遍历就行了。(本文不负责讲解迭代器,若想详细学习,见《C++ STL迭代器完全指南:从原理到实战》)

所以我们用这段代码就能过这道题。是不是挺简便的。


本文到这里就差不多要结束了,多谢浏览。

赞(0)
未经允许不得转载:171主机测评 » 去重排序c++(绝非正解)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址