• [洛谷] P1097 [NOIP2007 提高组] 统计数字


    1.题目

    题目背景

    #警告:数据可能存在加强

    题目描述

    某次科研调查时得到了 n n n个自然数,每个数均不超过 1500000000 ( 1.5 × 1 0 9 ) 1500000000(1.5 \times 10^9) 1500000000(1.5×109)。已知不相同的数不超过 10000 10000 10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。

    输入格式

    n + 1 n+1 n+1行。

    第一行是整数 n n n,表示自然数的个数;

    2 2 2 n + 1 n+1 n+1每行一个自然数。

    输出格式

    m m m行( m m m n n n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。

    每行输出 2 2 2个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

    样例输入 #1

    8
    2
    4
    2
    4
    5
    100
    2
    100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    样例输出 #1

    2 3
    4 2
    5 1
    100 2
    
    • 1
    • 2
    • 3
    • 4

    提示

    40 % 40\% 40%的数据满足: 1 ≤ n ≤ 1000 1 \le n \le 1000 1n1000

    80 % 80\% 80%的数据满足: 1 ≤ n ≤ 50000 1 \le n \le 50000 1n50000

    100 % 100\% 100%的数据满足: 1 ≤ n ≤ 200000 1 \le n \le 200000 1n200000,每个数均不超过 1500000000 ( 1.5 × 1 0 9 ) 1500 000 000(1.5 \times 10^9) 1500000000(1.5×109)

    NOIP 2007 提高第一题

    2.分析

    题目给出的数据范围过大,不可能开出1.5*109 大小的数组存储每个数字并计数
    考虑使用map容器[可视为可开足够大的变长数组、实际为红黑树]

    注意:map包含自动排序!!!

    3.代码

    1.map AC

    #include 
    using namespace std;
    #include 
    map<int, int> m;
    int n;
    int main()
    {
    	int n;
    	scanf("%d", &n);
    	while (n--)
    	{
    		int x;
    		scanf("%d", &x);
    		m[x]++;
    	}
    
    	for (auto x : m)
    		printf("%d %d\n", x.first, x.second);
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    2.map + set AC (map已经自动排序了,没必要使用set,练习使用多个stl的做法)

    #include 
    using namespace std;
    //set + map
    #include 
    #include 
    map<int, int> mp;  //计数
    set<int> st;   //自动去重 + 排序
    int main()
    {
    	int t;
    	scanf("%d", &t);
    	while (t--)
    	{
    		int x;
    		scanf("%d", &x);
    		mp[x]++;
    		st.insert(x);
    	}
    	for (auto x : st)
    		printf("%d %d\n", x, mp[x]);
    	/*等价于下列写法
    	for (set::iterator it = st.begin(); it != st.end(); ++it)
    		printf("%d %d\n", *it, mp[*it]);*/
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述

    4.总结

    掌握必要的stl容器还是很有必要的~
    map、set容器的遍历及其它知识点,请点击链接查看

    5.更新日志

    2022.8.27 整理

    欢迎交流、讨论、指正~
    不正确、不理解之处欢迎评论留言~

  • 相关阅读:
    CKA考题[k8s1.24]
    模拟电路和数字电路
    Python3初步实践教程概要
    基于SSH的酒店管理系统
    云原生之K8S------Pod的基础概念
    2022 ICLR | Geodiff:分子构象几何扩散生成模型
    服务器迁移:无缝过渡指南
    Unity BatchRendererGroup 在低端设备上也实现高帧率
    单调队列优化DP
    JDK发布信息、历史及未来规划
  • 原文地址:https://blog.csdn.net/qq_60404548/article/details/126554712