HDU 1029

Ignatius and the Princess IV

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32767 K (Java/Others)
Total Submission(s): 35692    Accepted Submission(s): 15574


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
 

Author
Ignatius.L
 

Recommend
We have carefully selected several similar problems for you:   1040  1074  1003  1171  1203 
 

本题解析:
法一:(暴力出奇迹)
我也就不说啥了,直接上代码好了(智商- -)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 1000000
int visit[maxn];
bool cmp(int a, int b)
{
    return a > b;
}

int main(){
    int n;
    int tmp;

    while(scanf("%d", &n) == 1)
    {
        int times[n + 1];
        memset(visit, 0, sizeof(visit));
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &tmp);
            visit[tmp]++;
            times[i] = tmp;
        }
        for(int i = 0; i < n; i++)
        {
            if(visit[times[i]] >= (n + 1) / 2)
            {
                printf("%d\n", times[i]);
                break;
            }
        }
    }
	return 0;
}
法二:(敲重点!!!其实是很巧妙的数学题~mark一下)
我们读题,题目中要求出现次数大于等于(n+1)/2的数,那么反过来说,也就是其他的数字出现的次数都小于(n+1)/2。
那么想一想,如果出现次数大于等于(n+1)/2的数算正,出现次数小于(n+1)/2的数算负,那么两两抵消之后,如果我们假设的这个数就是解的话,那么最后抵消的结果仍然是正的。如果是负的,也就是说当前的这个就可能是解,那么继续判断。
依此写出下列代码:
#include<iostream>
#include<cstdio>
using namespace std;

int main(){
    int n, x, y;
    int t;
    int i;
    while(scanf("%d", &n) == 1)
    {
        scanf("%d", &x);//我们先假设第一次输入的就是答案
        t = 1;
        
        for(i = 1; i < n; i++)
        {
            scanf("%d", &y);
            if(y == x)//如果相等,正++
                t++;
            else 
            {
                if(t == 0)//如果抵消的结果是负的,那么当前解就是暂时的答案.
                    x = y;
                else //否则,正--
                    t--;
            }
        }
        printf("%d\n", x);
    }
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值