[UVA][Trie] 10975 - Dueue's Quiz@Morris' Blog|PChome Online 人新台
2013-03-12 09:17:32| 人481| 回0 | 上一篇 | 下一篇

[UVA][Trie] 10975 - Dueue's Quiz

0 收藏 0 0 站台


Problem L

Dueue’s Quiz

Hesam Dueue Bararie is the showman of a very popular TV quiz: “Bararian Nights”. In this quiz, there is a big table of letters with some words hidden in it among diagonal, vertical or horizontal directions. During the quiz, Dueue tells each one of the contestants a word and they must find the total number of occurrences of that word in the table.

Recently, Milk-Farhaad has decided to participate in this TV quiz and because cheating is permitted during this quiz (!), he wants you to help him by writing a computer program.

By the way, Milk-Farhaad has bought the whole dictionary and configurations of the table from Dueue. All he need is a computer program which calculates the total number of occurrences for each word of the dictionary in the table.

You can see one sample of this table in figure 1. All occurrences of the word “hello” are circled in that. Also, the total number of occurrences of the word “madam” is equal to 2 because it must be counted twice: one from left to right and the other one from right to left.

 

 

Figure 1. Dueue’s Table

 

The Input

The first line of the input file is an integer which is the number of test cases. The first line of each test case is an integer  which is the number of words in the dictionary that should be used for this test case.  After that, comes D  lines each of which containing a word, having length of no more than 1000 characters, in the dictionary. Words are all constructed from lowercase letters: a…z.

Then, comes a line containing an integer , the total number of queries for the test case. For each query, there will be two integers which are the number of rows and the number of columns of the table respectively. Next, there are M lines each one containing N characters representing the configuration of each table of the quiz.

 

The Output

For each test case, your program should write a line with the phrase “Test Case #i” in which i is the index of the current test case starting from 1. Then comes the answer for each query in that test case. The answer to each query starts with a line containing the phrase “Query #j”. Then, all the words from dictionary which actually occurred in the table of that query should be listed one in each line (or each in one line!) together with their total number of occurrences in the given table. These words must be sorted in alphabetical order. There should be an empty line after the output for each test case.

 

 

Sample Input

1

4

hello

bye

one

two

2

3 3

bye

okk

res

3 3

one

wzq

too

 

Sample Output

Test Case #1

Query #1

bye 1

Query #2

one 1

two 1

 


Amirkabir University of Technology - Local Contest - Round #2


用存池加快速度,不使用配置。

建一棵 keyword tree (Trie),所有字串可能,去搜整 Trie,遇到哪些就哪些字出。

用 AC automation 效果不好,原因是似乎有稀疏。

Trie 0.232 s
AC automation 2.308 s



// 0.232 s

#include <stdio.h>
#include <string.h>
#include <map>
#include <iostream>
#include <algorithm>
#define rename(c) (c-'a')
using namespace std;
struct Node {
    Node *next[26];
    int label; // which word end.
    void init() {
        label = -1;
        memset(next, 0, sizeof(next));
    }
};
Node BUF[650000];
int BUFsize;
int insert_Trie(char str[], Node *root, int label) {
    static Node *p;
    static int i, idx;
    p = root;
    for(i = 0; str[i]; i++) {
        idx = rename(str[i]);
        if(p->next[idx] == NULL) {
            BUFsize++;
            BUF[BUFsize].init();
            p->next[idx] = &BUF[BUFsize];
        }
        p = p->next[idx];
    }
    if(p->label < 0) {
        p->label = label;
        return 1;
    }
    return 0;
}
char T[15000][1005], g[105][105];
int D[][2] = {{0,1},{1,0},{-1,0},{0,-1},
                {1,1},{1,-1},{-1,1},{-1,-1}};
int main() {
    int t, cases = 0;
    scanf("%d", &t);
    getchar();
    int n, q, i, j, k;
    while(t--) {
        scanf("%d", &n);
        BUFsize = 0;
        BUF[BUFsize].init();
        Node *root = &BUF[BUFsize];
        Node *p;
    nbsp;   while(getchar() != '\n');
        for(i = 0, j = 0; i < n; i++) { // offline process
            gets(T[j]);
            j += insert_Trie(T[j], root, j);
        }
        n = j;
        scanf("%d", &q);
        printf("Test Case #%d\n", ++cases);
        int a, b, x, y, dir, idx, qcases = 0;
        while(q--) {
            printf("Query #%d\n", ++qcases);
            scanf("%d %d", &a, &b);
            while(getchar() != '\n');
            for(i = 0; i < a; i++)
                gets(g[i]);
            int cnt_mark[15000] = {};
            map<string, int> output;
            for(i = 0; i < a; i++) {
                for(j = 0; j < b; j++) {
                    for(dir = 0; dir < 8; dir++) {
                        p = root;
                        x = i, y = j;
                        while(p != NULL && x < a && x >= 0 && y < b && y >= 0) {
                            idx = rename(g[x][y]);
                            if(p->next[idx] == NULL)
                                break;
                            p = p->next[idx];
                            if(p->label >= 0)
                                cnt_mark[p->label]++;
                            x += D[dir][0], y += D[dir][1];
                        }
                    }
                }
            }
            for(i = 0; i < n; i++)
                if(cnt_mark[i])
                    output[T[i]] = cnt_mark[i];
            for(map<string, int>::iterator it = output.begin();
                it != output.end(); it++)
                printf("%s %d\n", (it->first).c_str(), it->second);
        }
        puts("");
    }
    return 0;
}


附 AC automation 的做法

//2.308 s

#include <stdio.h>
#include <string.h>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
#define rename(c) (c-'a')
using namespace std;
struct Node {
    Node *next[26], *fail;
    int label; // which word end.
    /*Node() {
        label = -1;
        memset(next, 0, sizeof(next));
    }*/
    void init() {
        label = -1;
        fail = NULL;
        memset(next, 0, sizeof(next));
    }
};
Node BUF[625000];
int BUFsize;
void insert_Trie(char str[], Node *root, int label) {
    static Node *p;
    static int i, idx;
    p = root;
    for(i = 0; str[i]; i++) {
        idx = rename(str[i]);
        if(p->next[idx] == NULL) {
            //p->next[idx] = new Node();
            BUFsize++;
            BUF[BUFsize].init();
            p->next[idx] = &BUF[BUFsize];
        }
        p = p->next[idx];
    }
    p->label = label;
}
void build_ACautomation(Node *root) {
    queue<Node*> Q;
    Node *nd, *p;
    root->fail = NULL;
    Q.push(root);
    while(!Q.empty()) {
        nd = Q.front(), Q.pop();
        for(int i = 0; i < 26; i++) {
            if(nd->next[i] == NULL)
                continue;
            Q.push(nd->next[i]);
            p = nd->fail;
            while(p != NULL && p->next[i] == NULL)
                p = p->fail;
            if(p == NULL)
                nd->next[i]->fail = root;
            else
                nd->next[i]->fail = p->next[i];
        }
    }
}
void query_ACautonmation(char *str, Node *root, int *exist_mark) {
    static Node *p, *q;
    static int i, idx;
    p = root;
    for(i = 0; str[i]; i++) {
        idx = rename(str[i]);
        while(p != root && p->next[idx] == NULL)
            p = p->fail;
        p = p->next[idx];
        p = (p == NULL) ? root : p;
        q = p;
        while(q != root) {
            exist_mark[q->label]++;
            q = q->fail;
        }
    }
}
void free_Trie(Node *root) {
    queue<Node*> Q;
    Node *nd;
    while(!Q.empty()) {
        nd = Q.front(), Q.pop();
        for(int i = 0; i < 26; i++) {
            if(nd->next[i] != NULL)
                Q.push(nd->next[i]);
        }
        delete nd;
    }
}
char T[15000][1005], g[105][105], S[1024];
int main() {
    int t, cases = 0;
    scanf("%d", &t);
    getchar();
    int n, q, i, j, k;
    while(t--) {
        scanf("%d", &n);
        BUFsize = 0;
        BUF[BUFsize].init();
        //Node *root = new Node();
        Node *root = &BUF[BUFsize];
        Node *p;
        while(getchar() != '\n');
        for(i = 0; i < n; i++) { // offline process
            gets(T[i]);
            insert_Trie(T[i], root, i);
        }
        scanf("%d", &q);
        printf("Test Case #%d\n", ++cases);
        int a, b, x, y, dir, idx, qcases = 0;
        while(q--) {
            printf("Query #%d\n", ++qcases);
            scanf("%d %d", &a, &b);
            while(getchar() != '\n');
            for(i = 0; i < a; i++)
                gets(g[i]);
            build_ACautomation(root);
            int cnt_mark[15000] = {};
            map<string, int> output;
            int idx;
            for(i = 0; i < a; i++) { // row left-right
                p = root;
                x = i, y = 0, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    y++;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 0; i < a; i++) { // row right-left
                p = root;
                x = i, y = b-1, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    y--;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 0; i < b; i++) { // column left-right
                p = root;
                x = 0, y = i, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    x++;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 0; i < b; i++) { // column right-left
                p = root;
                x = a-1, y = i, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    x--;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 0; i < a; i++) { // slide down
                p = root;
                x = i, y = 0, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    x++, y++;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
                for(j = 0, k = idx-1; j < k; j++, k--)
                    swap(S[j], S[k]);
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 1; i < b; i++) { // slide down
                p = root;
                x = 0, y = i, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    x++, y++;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
                for(j = 0, k = idx-1; j < k; j++, k--)
                    swap(S[j], S[k]);
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 0; i < a; i++) { // slide up
                p = root;
                x = i, y = 0, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    x--, y++;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
                for(j = 0, k = idx-1; j < k; j++, k--)
                    swap(S[j], S[k]);
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 1; i < b; i++) { // slide up
                p = root;
                x = a-1, y = i, idx = 0;
                while(x < a && x >= 0 && y < b && y >= 0) {
                    S[idx++] = g[x][y];
                    x--, y++;
                }
                S[idx] = '\0';
                query_ACautonmation(S, root, cnt_mark);
                for(j = 0, k = idx-1; j < k; j++, k--)
                    swap(S[j], S[k]);
                query_ACautonmation(S, root, cnt_mark);
            }
            for(i = 0; i < n; i++)
                if(cnt_mark[i])
                    output[T[i]] = cnt_mark[i];
            for(map<string, int>::iterator it = output.begin();
                it != output.end(); it++)
                printf("%s %d\n", (it->first).c_str(), it->second);
        }
        puts("");
        //free_Trie(root);
    }
    return 0;
}
/*
1
1
a
1
1 1
a
*/



台: Morris
人(481) | 回(0)| 推 (0)| 收藏 (0)|
全站分: 不分 | 人分: UVA |
此分下一篇:[UVA][大] 11113 - Continuous Fractions
此分上一篇:[UVA][最小文][LCS] 11404 - Palindromic Subsequence

是 (若未登入"人新台"看不到回覆唷!)
* 入:
入片中算式的果(可能0) 
(有*必填)
TOP
全文
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86