UVALive 6133 Cellphone Typing(字典树)

来源:互联网 发布:淄博优化网站排名 编辑:程序博客网 时间:2024/05/16 17:33

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


0 0
原创粉丝点击