杭电OJ(HDOJ)1029题:Ignatius and the Princess IV(数论)

题意:

给出一个长度为N(1<=N<=999999)的序列,求出序列至少出现(N+1)/2次的元素。

示例输入:

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

示例输出:

3

5

1

解决方案1:

先举个例子:

设N=5,序列1为:(1 3 2 3 3)序列2为:(1 3 4 3 3 )序列3为:(3 5 3 6 3 ) ;

排序后:序列1为:(1 2 3 3 3)序列2为:(1 3 3 3 4 )序列3为:(3 3 3 5 6 ) ;

因为题目保证了序列中有一个元素会出现(N+1)/2次,所以将序列排序后,出现(N+1)/2次的元素总会在排序后该序列的中间位置。

最后输出下标为[N/2]的元素就可以了。

#include<iostream>
#include<algorithm>
using namespace std;
int arr[999999];
int cmp(int a,int b)
{
    if(a<=b)
        return 1;
    else
        return 0;
}
int main()
{
    int n,i;
    while(cin>>n)
    {
        for(i=0;i<n;i++)
            cin>>arr[i];
        sort(arr,arr+n,cmp);
        cout<<arr[n/2]<<endl;
    }
    return 0;
}


解决方案2:

还是抓住所求元素出现的次数(N+1)/2的特点。

因为保证了所求元素出现的次数(N+1)/2次,其它元素出现的次数为N-[(N+1)/2],两式相减等于1(当N为奇数时),所以最后没有消除的数就是所求的数

设N=5,序列为:(1 3 2 3 3),1 3这个两个元素消除,剩下(2 3 3),2 3 这个两个元素消除就是剩下(3),那么这个3就是所求的数。

#include"stdio.h"
int main()
{
    int a,temp,count,n;
    while(scanf("%d",&n)!=EOF)
    {
        count=0;
        while(n--)
        {
            scanf("%d",&a);
            if(count==0)
            {
                temp=a;
                count=1;
            }
            else
            {
                if(temp==a)
                    count++;
                else
                    count--;
            }
        }

        printf("%d\n",temp);
    }
}




你可能感兴趣的:(算法,ACM,杭电)