【题目网址】
http://www.lydsy.com/JudgeOnline/problem.php?id=2456
【题目描述】
给你一个n个数的数列,其中某个数出现了超过n div 2次即众数,请你找出那个数。
100%的数据,n<=500000,数列中每个数<=maxlongint。
时间限制:1sec 内存限制:1MB(敲黑板)
【题解】
玄学卡内存题,网上流行一种利用抵消思想的神算法。在这里提供另一种利用拆分思想的做法。
如果一个数是众数,那么它的每一位都会出现超过n/2次,所以只需要把每个数拆开统计即可。
【代码1】
#include<cstdio>
using namespace std;
int cnt[10][10];//cnt[i][j]表示倒数第i位为j的数的数量
int main()
{
int n;
scanf("%d",&n);
for(int k=0;k<n;k++)
{
int tmp;
scanf("%d",&tmp);
int pos=0;
while(tmp)
{
cnt[pos][tmp%10]++;
tmp/=10;
pos++;
}
}
int ans=0;
for(int i=9;i>=0;i--)
{
for(int j=0;j<10;j++)
{
if(cnt[i][j]>n/2)
{
ans*=10;
ans+=j;
}
}
}
printf("%d\n",ans);
return 0;
}
【代码2】(我觉得这个代码更直观易懂一些)
#include<cstdio>
using namespace std;
const int MOD=2000;
int c1[MOD],c2[MOD],c3[MOD];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int t;
scanf("%d",&t);
c1[t/MOD/MOD]++;
c2[t/MOD%MOD]++;
c3[t%MOD]++;
}
int ans=0;
for(int i=0;i<MOD;i++)
{
if(c1[i]>n/2)
{
ans+=i*MOD*MOD;
}
if(c2[i]>n/2)
{
ans+=i*MOD;
}
if(c3[i]>n/2)
{
ans+=i;
}
}
printf("%d\n",ans);
return 0;
}