来http://www.programfan.com/club/时间不短了,也比较关注论坛每星期举行的程序比赛。。限于能力有限,每次都是做为一个旁观者。这次比赛是我第一次提交程序。结果也如期所料正确,不过速度太慢了。。虽然在这次比赛中,我是无足轻重的,但是对于我来说也是比较重要的。通过比赛我学到不少东西,学会了测试程序的运行时间。。(嘿嘿,以后有事没事都测试了)废话不多说了,看内容。
比赛题目:http://www.programfan.com/club/showbbs.asp?id=188623
比赛结果:http://www.programfan.com/club/showbbs.asp?id=189050&page=1
/*第1题:
半数问题,给定整型数组vote[], 其大小为n,数组中任一元素均为自然数i (i = 1,2,3,...)。
规定函数接口:int Majority (int vote[], int n)
在vote[]中,可能存在一个自然数i,其个数m 超过半数,即m > n/2。若存在这样的i,函数Majority返回m,否则函数返回0。
例:
vote[5] = {1,8,1,100,1}; 其大小为 5。
因为自然数1的个数为3,超过半数,那么调用Majority将返回 3。
题目要求:编写规定函数接口 Majority。
*/
#include <iostream>
#include <time.h>
using namespace std;
int Majority(int vote[],int n)
{
int *p= vote;
int m;
for(int i = 0;i < n-1;i++)
{
m = 1;
for(int j = i+1;j < n;j++)
{
if(p[i] == *(p+j))
m++;
}
if(m > n/2)
return m;
}
return 0;
}
/////////////////////////////////////////////////下面是用来测试函数的///////////////////////////////////////////////////
int main()
{
// int vote[10]={2,3,2,3,3,4,2,2,2,2};
int vote[10];
for(int i=0;i<10;i++)
cin >> vote[i];
cout<< Majority(vote,10) <<endl;
return 0;
}
/////////////////////////////////////////////////////用来测试函数运行时间的主函数//////////////////////////////////////////////
int main()
{
int t1,t2;
int n = 20000,step = 10;
int *vote = new int[n];//分配空间
for(int i = 0; i < n; i++)//生成测试数据
{
vote[i] = rand() % step + 1;
}
t1=clock();//clock返回程序运行得时间,毫秒.
Majority(vote,n);
t2=clock();
cout << t2 - t1 << "ms"<<endl;//运行时间差是fun函数得时间
return 0;
}
///////////////////////////来看下,题目的标准算法///////////////////////////////////////////
题目标准算法:
/*
*把个数可能超过半数的自然数,称为候选数。
*用 个数抵消,但数目相对多的自然数一定能存活下来 的思想:
*按顺序遍历数组,并选定第一个数为候选数,如果下一个自然数等于候选数,那个其个数
*加1,否则其个数减 1(个数抵消)。当候选数当前个数为0时,
*我们就选定下一数为候选数,这样遍历结束时,如果最后那个候选数的个数不为0,
*那么我们可以相信倘若数组的确存在超过半数的自然数,
*那么它一定是最后的那个候选数。
*
*第一次遍历数组,可找出候选数(若个数大于半数,不管怎么抵消,一定能活下来)。
*第二次遍历数组,计算候选数的个数,确定是否超过半数。
*/
int majority(int vote[], int n)
{
int candidate; // 当前候选自然数 i
int vote_count; // 当前候选数 i 的当前个数
int count; // 最后确定的候选数 i的实际个数
int i;
candidate = vote[0]; // 选定数组第一个元素为候选数
vote_count = 1; // 候选数的当前个数为 1个
for (i = 1; i < n; i++){ // 遍历数组元素
if (vote_count == 0) {// 如果候选数当前个数为 0个
candidate = vote[i]; // 那么选定下一个数为候选数
vote_count = 1; //
}
else if (candidate == vote[i]) //如果下一个数等于当前候选数
vote_count++; // 那么候选数当前个数加 1
else
vote_count--; // 如果不等于,那么当前个数减 1
}
if (vote_count == 0) // 如果最后候选数当前个数为零,
return 0; // 那么它的个数一定小于半数
for (i = 0, count = 0; i < n; i++)
if (vote[i] == candidate)
count++; //计算候选数的实际个数
return count > n/2 ? count : 0;
}