~~超过半数的数字
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1552
超过半数的数字 | |||||
|
|||||
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 ![]() 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了,虽然有点悬,可是我们几个都没想到二分~~ ![]() 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> |