題目鏈接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34981
題意:N個單詞的字典,求這N個的單詞的平均敲擊鍵盤的次數,也就是敲擊鍵盤總數/N個單詞。
題解:建字典樹,查詢時遇到分支就加1.
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2000005;
const int MAXM = 30;
char s[MAXN][100];
struct Trie {
int ch[MAXN][MAXM], val[MAXN];
int sz;
void init() {
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
memset(val, 0, sizeof(val));
}
int idx(char c) {
return c - 'a';
}
void insert(char *s) {
int u = 0, n = strlen(s);
for (int i = 0; i < n; i++) {
int c = idx(s[i]);
if (!ch[u][c]) {
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz]++;
ch[u][c] = sz++;
} else {
val[ch[u][c]]++;
}
u = ch[u][c];
}
}
int query(char *s) {
int res = 1;
int u = 0, n = strlen(s);
int ls;
for (int i = 0; i < n; i++) {
int c = idx(s[i]);
if (i == 0) {
ls = val[ch[u][c]];
} else {
int cx = val[ch[u][c]];
if (cx != ls) {
res++;
ls = cx;
}
}
u = ch[u][c];
if (ls == 1) {
break;
}
}
return res;
}
} AC;
int main() {
#ifdef ONLINE_JUDGE
#else
freopen("test.in", "r", stdin);
#endif
int n;
while (~scanf("%d", &n)) {
AC.init();
for (int i = 1; i <= n; i++) {
scanf("%s", s[i]);
AC.insert(s[i]);
}
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += AC.query(s[i]);
}
printf("%.2f\n", ans * 1.0 / (n * 1.0));
}
return 0;
}