聪明人都懂第二个图中的小球表示啥

首师大附中互测题:99999999海岛帝国后传:算法大会【D001】

【D001】99999999海岛帝国后传:算法大会【难度:D】

——————————————————————————————————————————————————————————————————————————————————————

【题目要求】

 YSF经过百般思考后,决定召开一个“煽风点火”,来召集全世界优秀的计算机人士。算法大会只有一道题,是WXJ && LJX合力编写、研究出来的算法设计精品:(以下为YSF的发言稿)

    大家还记得这样一道超水,水的不能再水的题吗?(当然不是A+B问题啦)题目如上。

    总体说,就是高效实现。

    保证有且只有一个数符合条件。

【输入输出及要求】如图(阅读者:真懒QAQ)

【其它要求】

 运行时间限制:50ms

 n<=10^10,享受痛苦吧!

【试题分析】50ms达到10^10我想问的是出题者你在逗我吗?通过度娘我发现这是一个著名的主元素问题,主要思想就是通过代码选出最有可能当选的人也就是候选人。既然如此可以得到这  样的一个结论:在元素数组中,删去不同的两个元素,数组的主元素保持不变。按照这样的思路,我们可以不断缩小问题的规模,最终使问题得解:
 设置变量Seed用于存储当前候选元素,初始化为数组首元素a[0];
 设置变量count用于控制候选元素,初始化为1;
 从第二个元素a[1]开始遍历数组,并与Seed相比较:相同,则count加1,读入下一个元素;
 不同,则count减1,读入下一个元素:相当于删去两个不同元素,缩小问题规模;如果count小于0则Seed不是主元素候选,读入下一个元素,count加1。
 这样一次遍历之后,得到的Seed就是主元素的候选;但因为最终得到的Seed元素有可能是序列最末位的两个元素之一,所以还需要验证。我们再次遍历数组,得到Seed出现的次数,与总数的一半比较来验证。

 总的来说这个方法的效率非常高可以达到比O(n)还好。所以,完美解决。哼(ˉ(∞)ˉ)唧

【代码】

 

#include <iostream>
using namespace std;

int MajorityElement( int *a, int n)
{
	int k, i;
	int elem;
	k = 1;
	elem = a[0];
	for( i = 1; i <n; i++ )
	{
		if( a[i]==elem ) k++;
		else
		{
			k--;
			if( k == 0 ) { k = 1; elem = a[i]; }
		}
	}
	return elem;
}
int main(int argc, char* argv[])
{
	int n;
	cin>>n;
	int a[n];
	for(int i=1;i<n+1;i++) cin>>a[i];
	cout<<MajorityElement(a,sizeof(a)/sizeof(a[0]))<<endl;
}

 

posted @ 2016-06-22 10:33  LJX李家鑫  阅读(284)  评论(0编辑  收藏  举报