~~超过半数的数字

http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1552

超过半数的数字
Time Limit: 2500 MS Memory Limit: 7000 K
Total Submit: 267(14 users) Total Accepted: 107(10 users) Special Judge: No
Description

给定一个n元素的序列,其中存放的都是整数类型的数据。现在保证给出的序列中有一个数,这个数的个数超过整个序列元素总个数的一半,请你找出这个数是多少。

 

Input

输入数据第一行为一个整数T(T<=15)为测试数据的组数。接下来是T组测试数据。

每组测试数据的第一行为一个整数n(1 <= n <= 1000000)。代表序列中元素的个数。

接下来是序列中存放的n个数值。每个数值的范围在[0,2000000]内。

Output

输出数量过半的那个数字。保证每组数据必有唯一的解。

Sample Input

1

10

2 1 2 3 4 5 2 2 2 2

Sample Output
2
Author

ZeroPointer@HRBUST

题意就不多说了,注意题目的Time Limit和Memory Limit,就知道了,如果开2000000的数组遍历就会MLE了,如果sort后取中位数就会TLE了,so……

存在侥幸心理拿rand函数玩了几次,都华丽丽的WA,毕竟每次对的几率为1/2,而且是15次测试结果,果断WA。。。

经过别人提醒,才想到了,每次删掉两个不想等的数字,一直删。。。一直删。。。

因为答案要求出现次数超过n/2的数,那么剩下的那个数字一定是答案了。1400+ms

View Code
 1 #include <cstdio>
 2 int main(){
 3     int t,a,b,c,n;
 4     scanf("%d",&t);
 5     while(t--){
 6         scanf("%d%d",&n,&a);
 7         c=1;
 8         while(--n){
 9             scanf("%d",&b);
10             if(b==a) ++c;
11             else if(c==1) a=b;
12             else --c;
13         }
14         printf("%d\n",a);
15     }
16 }

这里还有个小老乡的代码,用二分2331ms A了,虽然有点悬,可是我们几个都没想到二分~~

View Code
 1 /******author :rihkddd********/
 2 #include <stdio.h>
 3 #include <iostream>
 4 #include <math.h>
 5 #include <string.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <map>
 9 #include <string>
10 #include <list>
11 #include <cstdlib>
12 
13 #define max(a,b) ((a)>(b)?(a):(b))
14 #define min(a,b) ((a)<(b)?(a):(b))
15 #define abs(x) ((x)>0?(x):(-x))
16 
17 using namespace std;
18 int Number[1000010];
19 int main()
20 {
21     int i, j, k ,l ,m ,n ,T ;
22     scanf("%d", &T);
23     while(T--)
24     {
25         scanf("%d", &n);
26         for (i = 0; i < n; ++i)
27         {
28             scanf("%d", &Number[i]);
29         }
30         int left=0,right=2000000;
31         while(left<right)
32         {
33             int middle=(left+right)>>1,left_counter=0,right_counter=0;
34             for (i = 0; i < n; ++i)
35             {
36                 if(Number[i]<=middle)
37                     left_counter++;
38                 else
39                     right_counter++;
40             }
41             if(left_counter<right_counter)
42                 left=middle+1;
43             else
44                 right=middle;
45         }
46         printf("%d\n", left);
47     }
48     
49     return 0;
50 }

 

 额外补充一下,输出二进制:

#include<iostream>
#include<bitset>
using namespace std;
int main()
{
        int u;
        cin>>u;
        bitset<32> b(u);
        cout<<b<<endl;
        return 0;
}

posted @ 2012-10-12 18:09  _sunshine  阅读(501)  评论(0编辑  收藏  举报