ural 1542 字典树(思维)

来源:互联网 发布:淘宝哪家supreme复刻 编辑:程序博客网 时间:2024/06/07 17:51

题目:http://acm.timus.ru/problem.aspx?space=1&num=1542
题意:

给出n个单词和各自出现的频率,然后给出m个某些单词的开头,要求找出频率最高不超过10个的以这些字符串开头的单词。

分析:

显然是字典树的题目,如果把单词建字典树,然后对于每个开头字符串,都查询一遍字典树,显然会超时。
所以逆向思考一下,把开头字符串建立字典树,然后查询每个单词,每个开头字符串找出不超过10个单词,这样就很容易实现了~~

#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <string>#include <map>#include <cmath>#include <queue>#include <set>using namespace std;typedef long long ll;typedef pair<int, int>pii;const double PI = acos (-1.0);const int INF = 0x3f3f3f3f;const int N = 3e5 + 9;int to[N], cnt[N];char ans[N][11][16], s[16];struct Item {    char arr[16];    int num;    bool operator < (const Item& rhs) const {        if (num == rhs.num) return strcmp (arr, rhs.arr) < 0 ? 1 : 0;        return num > rhs.num;    }} p[N];const int maxnode = 3e5 + 10;struct Trie {    int ch[maxnode][26];    int val[maxnode];    int sz;    void clear() {        sz = 1;        memset (val, 0, sizeof (val) );        memset (ch[0], 0, sizeof (ch[0]) );    }    int idx (char c) {        return c - 'a';    }    void insert (const char *s, int id) {        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]) );                ch[u][c] = sz++;            }            u = ch[u][c];        }        if (!val[u]) val[u] = id, to[id] = id;        else to[id] = val[u];    }    void search (const char *s) {        int u = 0, len = strlen (s);        for (int i = 0; i < len; i++) {            int c = idx (s[i]);            u = ch[u][c];            if (u) {                if (val[u] && cnt[val[u]] <= 9)                    strcpy (ans[val[u]][cnt[val[u]]++], s);            } else break;        }    }};Trie trie;int main() {    //freopen ("f.txt", "r", stdin);    int n, m;    trie.clear();    memset (cnt, 0, sizeof (cnt) );    scanf ("%d", &n);    for (int i = 1; i <= n; i++) scanf ("%s%d", p[i].arr, &p[i].num);    sort (p + 1, p + 1 + n);    scanf ("%d", &m);    for (int i = 1; i <= m; i++) {        scanf ("%s", s);        trie.insert (s, i);    }    for (int i = 1; i <= n; i++) {        trie.search (p[i].arr);    }    bool flag = 0;    for (int i = 1; i <= m; i++) {        if (flag) printf ("\n");        flag = 1;        for (int j = 0; j < cnt[to[i]]; j++)            printf ("%s\n", ans[to[i]][j]);    }    return 0;}
0 0
原创粉丝点击