题目链接: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); }