• Vijos1917 艾酱最喜欢的数字 [求绝对众数]


    1.题意:第一行一个数字N,表示一共有多少个数字,第二行N个数字,保证其中至少有一个数字出现次数超过一半,任务是求出这个出现最多的数。

    2.分析:本题是明显的求众数的问题,常规思路为开一个大数组,在读入数据的同时统计数据出现的次数,最后遍历出众数,显然的提交之后会MLE,因为题面上的数据范围为:

    40%的数据满足(n<=100)
    60%的数据满足(n<=1000000),内存大小限制128Mb
    70%的数据满足(n<=1000000),内存大小限制3Mb
    100%的数据满足(n<=1000000),且所使用内存大小不能超过1Mb

    所有输入数字为小于1000000007的非负整数。

    那么这里提供一个新的思路:即不用数组统计出现次数,因为最终关注的只是众数,无需记录所有信息。

    考察绝对众数的两个性质:(1)众数的出现次数严格大于总数字的一半;(2)删除数组中两个不同的数,绝对众数不变

    通过不断删除两个不同的数,最终剩下一个或者两个数的时候,留下的一定是单独的一个绝对众数(数组有奇数个数)或者两个绝对众数(数组有偶数个数)

    具体操作是维护两个变量num以及temp分别表示临时众数与当前读入的数字,一个num_cnt表示已经遇到的临时众数的数量

    当num != temp 则忽略这两个数:temp继续读入下一个数。num_cnt--

    当num = temp 则忽略temp,增加num的个数:temp继续读入下一个数,num_cnt++

    当num_cnt为0,选取下一个temp为num

    代码如下:

     1 # include <iostream>
     2 # include <cstdio>
     3 using namespace std;
     4 int N;
     5 int main()
     6 {
     7     while(scanf("%d",&N)!=EOF)
     8     {
     9         int num;
    10         int num_cnt=1;
    11         scanf("%d",&num);
    12         for(int i=1;i<N;i++)
    13         {
    14             int temp;
    15             scanf("%d",&temp);
    16             if(num_cnt==0)
    17             {
    18                 num=temp;
    19                 num_cnt=1;
    20                 continue;
    21             }
    22             if(temp==num)
    23                 num_cnt++;
    24             else
    25                 num_cnt--;
    26         }
    27         printf("%d
    ",num);
    28     }
    29     return 0;
    30 }
  • 相关阅读:
    poj2104 Kth-Number
    bzoj2120 数颜色
    hdu5145 NPY and girls
    bzoj2734 集合选数
    bzoj3732 NetWork
    bzoj2152 聪聪可可
    hdu2036(多边形面积)
    超大次幂思路
    hdu 2030 统计汉字个数
    Hibernate 配置文件与映射文件 总结
  • 原文地址:https://www.cnblogs.com/cnXuYang/p/7151487.html
Copyright © 2020-2023  润新知