Description
給你一個n個數的數列,其中某個數出現了超過n div 2次即衆數,請你找出那個數。
Input
第1行一個正整數n。
第2行n個正整數用空格隔開。
Output
一行一個正整數表示那個衆數。
Sample Input
5 3 2 3 1 3
Sample Output
3
Hint
100%的數據,n<=500000,數列中每個數<=maxlongint。
如: for(i=1;i<=n-j;i++)
{
if(map[i]==map[i+j])
break;
}
如果第i個數和第i+n/2個數相等,說明這個數就是衆數。結果超時。
My solution:
/*2016.3.15*/
Time Limit Exceed
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int map[500060];
int main()
{
int i,j,n,k;
while(scanf("%d",&n)==1&&n)
{
for(i=1;i<=n;i++)
scanf("%d",&map[i]);
j=n/2;
sort(map+1,map+n+1);
for(i=1;i<=n-j;i++)
{
if(map[i]==map[i+j])
break;
}
if(i<=n-j)
printf("%d\n",map[i]);
}
return 0;
}
看了別人的題解後,發現別人的方法好巧妙。注:因爲某個數出現超過n/2次(即:cnt>n/2),所以其它數字的個數總和m,必定滿足cnt>m。用個數最多的數字來消耗其它數字,最後剩下的必然只有原先個數最多的數字。
思想與HDU-1205相似。
Ac代碼:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int main()
{
int i,n,k,cnt,num;
while(scanf("%d",&n)==1&&n)
{
cnt=0;
num=0x3f3f3f3f;//初始化爲無窮大
for(i=1;i<=n;i++)
{
scanf("%d",&k);
if(k==num)
cnt++;
else
{
cnt--;//不相等,便消耗
if(cnt<0)//說明之前存的那個數字個數被消耗完了,從而說明它不是個數最多的數字
{
cnt=0;
num=k;//存進新的數字
}
}
}
printf("%d\n",num);
}
return 0;
}