杭电1029——出现(n+1)/2次的数

问题描述

Problem Description
“OK, you are not too bad, em… But you can never pass the next test.” feng5166 says.

“I will tell you an odd number N, and then N integers. There will be a special integer among them, you have to tell me which integer is the special one after I tell you all the integers.” feng5166 says.

“But what is the characteristic of the special integer?” Ignatius asks.

“The integer will appear at least (N+1)/2 times. If you can’t find the right integer, I will kill the Princess, and you will be my dinner, too. Hahahaha…..” feng5166 says.

Can you find the special integer for Ignatius?

Input
The input contains several test cases. Each test case contains two lines. The first line consists of an odd integer N(1<=N<=999999) which indicate the number of the integers feng5166 will tell our hero. The second line contains the N integers. The input is terminated by the end of file.

Output
For each test case, you have to output only one line which contains the special number you have found.

Sample Input
5
1 3 2 3 3
11
1 1 1 1 1 5 5 5 5 5 5
7
1 1 1 1 1 1 1

Sample Output
3
5
1

问题分析

题意:给你n(n是奇数)个整数,求出现(n+1)/2次的数。也就是在此序列中出现次数最多的数(超过一半了~)。

算法思想:如果a是序列中出现次数最多的数,假如在该序列中删除两个不同的数。那么a还是该序列中出现次数最多的数。很好理解,假如一个序列有2k+1(k是整数,题目中规定n是奇数)个整数,一开始a出现了k+1,是序列中出现次数最多的数。如果删除两个不同的数,此时分两种情况考虑:(1)删除的数据组含有a,则此时a出现的次数是k,序列元素的总个数为2k-1,a 仍然是序列中出现次数最多的数。(2)若删除的数据中不包含a,则a出现的次数为k+1,序列元素的总个数为2k-1。此时,a仍然是出现次数最多的数。

那么如何将上述思想运用到该题中呢?
举个例子:
1 3 2 3 3
最初,curIndex=0,指向数组中的第一个元素1,i=1,指向3,即数组中第2个元素,count=1。i不断向后扫描,如果,扫描到的数据等于curIndex指向的数据,则count++,否则count–。如果count=0,则说明出现了n对不同数据,则可以忽略他们,考虑其后的数据。比如说,当i扫描到第一个元素3的时候,count=0,此时出现了一对不同的数据。则可以忽略他们,考虑其后的元素2 3 3,curIndex重新指向2,i指向curIndex后面的一个数,count=1,继续扫描。当i扫描到2后面的3时,count=0。此时,又出现一对不同的数据,忽略他们,考虑其后的数据,即3。最后curIndex指向的数据既是所求的数据,此处为3。

AC代码

# include<stdio.h>
#include<malloc.h>

int main()
{
    int N,i;
    while(scanf("%d",&N)!=EOF)
    {
        int count=1,curIndex=0;
        int *num=(int *)malloc(N*sizeof(int));
        for(i=0;i<N;i++)
        {
            scanf("%d",num+i);
        }
        for(i=1;i<N;i++)
        {
            if(num[i]==num[curIndex])
                count++;
            else
                count--;
            if(count<=0)
            {
                count=1;
                curIndex=i+1;
                i=curIndex;
            }
        }
        printf("%d\n",num[curIndex]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值