【题目链接】
ybt 1186:出现次数超过一半的数
OpenJudge NOI 1.13 28:出现次数超过一半的数
【题目考点】
1. 散列存储
散列思想:将要存储的数值通过散列函数转为下标
散列函数:一个自变量为数值,函数值为下标的数学函数。数值与下标必须一一对应。
【解题思路】
该题中的数值范围为
−
50
∼
+
50
-50\sim +50
−50∼+50,数组下标只能是非负数,那么散列函数可以设为:下标 = 数值+50
。
设数组ct为计数数组,ct[i]表示数值
i
−
50
i-50
i−50的个数。
也就是说:ct[0]为-50的个数,ct[1]为-49的个数,…,ct[100]为50的个数。
输入数据,用计数数组做计数,遍历计数数组,如果某个数字出现的个数大于
n
/
2
n/2
n/2,那么输出这个数字。如果没有这样的数字输出no。
【题解代码】
写法1:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int ct[105] = {}, n, a;//ct[i+50] = j 表明数字i有j个
cin >> n;
for(int i = 1; i <= n; ++i)
{
cin >> a;
ct[a+50]++;
}
for(int i = -50; i <= 50; ++i)
{
if(ct[i+50] > n/2)
{
cout << i;
return 0;
}
}
cout << "no";
return 0;
}
写法2:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int ct[105] = {}, n, a;//ct[i] 表明数字i-50有j个
cin >> n;
for(int i = 1; i <= n; ++i)
{
cin >> a;
ct[a+50]++;//散列函数:下标=数值+50
}
for(int i = 0; i <= 100; ++i)
{
if(ct[i] > n/2)
{
cout << i-50;
return 0;
}
}
cout << "no";
return 0;
}