tyvj P3680 找妹子

    xiaoxiao2023-03-25  5

    P3680 找妹子

    时间: 1000ms / 空间: 1200KiB / Java类名: Main

    背景

    本题由 @fjzzq2002 提供,已奖励20金币。

    描述

    sps是zzq的好伙伴。

    sps一天叫来了许多个妹子。然后sps看了看这些妹子,说了m个数。这m个数中出现次数最多的数就是sps最喜欢的妹子的编号。因为sps非常专一,他最喜欢的妹子的编号出现的次数大于m的一半。

    你自然想知道一下sps最喜欢哪个妹子。

    m<=1000000。m个数均在int范围内的正数。

    注意看时空限制!

    输入格式

    第一行一个数m。

    第二行m个数。

    输出格式

    输出出现次数最多的数。

    备注

    空间1.2MB,连m个数都存不下。

    样例输入:

    8 2 3 3 2 3 3 2 3

    样例输出:

    3


    【分析】 解题思路如下:

    根据题目的规定,出现最多的数出现次数一定是总数的一半以上。在这里我用tmp记录当前的答案,用t来表示当前答案从记录的地方开始比不是这个答案的多的个数。

    这样说可能比较难懂。但是下面我们来模拟一组数据,以样例为例:

    8

    2 3 3 2 3 3 2 3

    首先我们读入样例的总数n=8,然后读入第一个数据2.下面我们暂且把2号妹子当做答案的妹子。那么现在我们就相当于从第一个数开始选择到第一个数,现在这些数中和所选的妹子相同的(即2)有一个,不同的有0个,我们就把t赋值为1。

    接下来,我们读入第二个数3,这时不同的妹子数就为1了,于是我们将t自减,变为0。

    再然后,我们读入第三个数3,不同妹子数变为2,再自减t,变为-1。这时,我们就决定不选择该妹子,而选择我们读入的妹子3记为tmp,将t清空重新计算。

    之后一直这样计算,就能得到最后的答案。

    不严密的证明:即证明对于一组数其中的一个数,总有从其中的一个数字相同的点出发会在后面的判断中始终不改变tmp,且第一个tmp一定是最终的答案。

    ∵这个数的出现次数大于总次数的一半

    我们假设这个最终的答案出现在一个位置。并且在之后会因为不同的妹子太多被覆盖。

    那么,不同的妹子数一定大于这个最终的答案数。

    ∴在下一次这个数出现时,这个数的剩余总个数一定仍然超过剩余数的总个数的一半。

    ∴以此类推,最终能够得到答案


    【代码】

    #include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define M(a) memset(a,0,sizeof a) #define fo(i,j,k) for(i=j;i<=k;i++) using namespace std; int n; inline int read() { int x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { int i,j,t=1; n=read(); int tmp=read(); fo(i,2,n) { j=read(); if(tmp==j) t++; else t--; if(t<0) tmp=j,t=1; } printf("%d\n",tmp); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1203940.html
    最新回复(0)