bzoj 2456 mode

 bzoj 2456 mode
Crawling in process...Crawling failedTime Limit:1000MS    Memory Limit:1024KB    64bit IO Format:%lld & %llu

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。

注:剛開始是把這些數存進數組,再排序,因爲至少有n/2+1個數相等,因此一定是一塊連續的區間,因爲某個數超過n/2次,所以在數組中查找長度爲n/2+1的區間。

如: 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;
}


發佈了144 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章