用户的昵称【哈希】
题目大意:
题目链接:http://10.156.17.250/JudgeOnline/showproblem?problem_id=1453(学校局域网)
给出一些人的昵称,求每个昵称有多少人在使用。不区分大小写。
思路:
这道题,模拟都能过。。。
我用了字符串哈希,定义哈希函数为
之后判断在里面是否存在,如果存在,那么就找到之前的位置,将(原来的位置加一),然后排序,输出即可。
跑的好慢啊QWQ暴力比这都还快。
代码:
#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
#define MOD 1000007
using namespace std;
int n,num,len,j,w[MOD+1];
string ha[MOD+1];
struct node
{
string s; //昵称
int a; //这个昵称的个数
}s[MOD+1];
void change(int x) //大写转小写
{
for (int i=0;i<len;i++)
if (s[x].s[i]>='A'&&s[x].s[i]<='Z') s[x].s[i]-=('A'-'a');
}
bool cmp(node x,node y)
{
return x.s<y.s;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
cin>>s[i].s;
len=s[i].s.size();
change(i); //转换
num=0;
for (int k=1;k<=s[i].s.size();k++)
num=(num+s[i].s[k-1]*k)%MOD; //hash函数(也许不够优美)
num%=MOD;
j=num%MOD;
while (ha[j]!=""&&ha[j]!=s[i].s)
j=(j+1)%MOD; //hash
if (ha[j]==s[i].s) //有过这个昵称
{
s[w[j]].a++; //原来昵称的位置加一
}
else
{
ha[j]=s[i].s; //储存
s[i].a++;
w[j]=i; //保存位置
}
}
sort(s+1,s+1+n,cmp);
for (int i=1;i<=n;i++)
if (s[i].a) //有这个昵称
cout<<s[i].s<<" "<<s[i].a<<"\n";
return 0;
}