栈模拟 woj Problem 1204 - 继续找相同

来源:互联网 发布:淘宝网孕妇夏装 编辑:程序博客网 时间:2024/06/07 01:31
Time Limit: 1000MS  Memory Limit: 5240KB  Difficulty: 5 Total Submit: 2280 Accepted: 477 Special Judge: No
Description

有 n 个整数, 其中有且仅有一个整数出现了 >= n/2.0 次 (n<=500000)

Input
每组数据第一行是 n, 然后接下来一行是 n 个整数, 请读入到 EOF
Output
输出每行一个整数, 即要找的这个数
Sample Input
9
5 5 5 5 5 1 2 3 4
Sample Output
5

问题分析:
problem 1203:数据量很大,必须要用O(n)的算法。

可以证明,对于一个包含n个元素的数组,如果有一个数字出现的次数大于n/2那么从这个数组中拿走任意两个不同的数,那个数字出现的次数仍然超过(n-2)/2
那么只要设计一个算法,每次从中取出两个数字,如果相同,则留下,不同则都移除。如果数组中不再有不同的数,那么就找到它了。
考虑用栈stack来实现
按顺序处理每一个数字:
如果栈空,入栈;
如果栈不过空,比较栈顶元素与当前数字:
   如果相同,该数字入栈
   如果不同,栈顶元素出栈
处理完所有数字后,栈里剩下的数字必然是同一个数字,也就是要求的结果。

而本题要找的那个数可能正好是n/2次。
可以讨论一下可能的情况:
1. n是奇数,OK,其实就是1203。
2. n是偶数,好吧,再分情况
   1) 出现了 > n / 2次,OK,还是1203。
   2) 出现了正好 n / 2次:完蛋,按照1203去做,最后栈空了
           ——那最后一次咱就不出栈了,看看剩下的两个数哪个出现得多就OK了。但是直接发现用c++栈操作
会超时,尝试模拟栈后ac

代码:
/*=============================================================================#     FileName: 1204.cpp#         Desc: #       Author: JxGuo#        Email: whu18707199852@gmail.com#      Version: 1.0#   LastChange: 2013-03-06 10:40:30#      History:=============================================================================*/#include<stdio.h>#include<stdlib.h>int num[500005];int main(){    int n;    while(scanf("%d",&n) != EOF)    {        int i;        int s1 = 0;        int t2;        int ans;        for(i = 0; i < n; i++)        {            scanf("%d",&num[i]);            if(s1 == 0)            {                s1++;                ans = num[i];            }            else if(ans == num[i])                s1++;            else                 s1--;        }        if(s1 > 0)            printf("%d\n",ans);        else        {            t2 = num[n-1];            int i,num1 = 0, num2  = 0;            for(i = 0; i < n; i++)            {                if(num[i] == ans)                    num1++;                else if(num[i] == t2)                    num2++;            }            if(num1 > num2)                printf("%d\n",ans);            else                printf("%d\n",t2);        }    }    return 0;}