题目链接:http://acm.fzu.edu.cn/problem.php?pid=1353
题目大意:给定100万个木头名称,相同的为一个种类,种类不超过1万,问每个种类出现的概率
解题思路:这题不复杂,简单排序同类的就扎堆了,然后直接判断也能卡时间卡过。正解是用Hash求解,由于每个名称最长是30,所以直接用个数组记录出现次数也不合适,会MLE.那就随机用某个hash算法求出对应的hash值,然后对MAX取余,会有些冲突,解决冲突的办法是价格vis数组,如果之前出现过就往后比较,如果没出现过就好办。原来hash活用如此简单,具体见代码。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAX 11000
struct node {
char str[31];
int cnt;
}arr[MAX];
int hash,tot;
int n,now,vis[MAX];;
char wood[100];
unsigned int ELFHash(char *str) {
unsigned int hash = 0;
unsigned int x = 0;
while (*str) {
hash = (hash<<4) + (*str++);
if ((x = hash & 0xF0000000L) != 0) {
hash ^= (x >> 24);
hash &= ~x;
}
}
return hash % MAX;
}
int cmp(node a,node b) {
return strcmp(a.str,b.str) < 0;
}
int main()
{
tot = n = 0;
while (gets(wood) != NULL) {
//以下代码为解决冲突用,很容易看懂的
n++,hash = ELFHash(wood);
while (vis[hash] && strcmp(arr[hash].str,wood))
hash = (hash + 1) % MAX;
if (vis[hash] == 0) {
tot++,vis[hash] = 1;
arr[hash].cnt = 1;
strcpy(arr[hash].str,wood);
}
else arr[hash].cnt++;
}
sort(arr,arr+MAX,cmp);
for (int i = MAX - tot; i < MAX; ++i)
printf("%s %.4lf\n",arr[i].str,arr[i].cnt * 100.0 / n);
}
http://blog.youkuaiyun.com/woshi250hua/article/details/7551083