poj 1997 trie树

Word Puzzle

Time Limit: 2000MS Memory Limit: 30000K
Total Submissions: 1113 Accepted: 494

Description

What a game collection it would be without famous and well known word puzzle. Also KOKODáKH contains this game. Typical word puzzle is a rectangular array filled with letters, and the list of words. The goal is to find the words form the list in the array and to score out all their letters. After scoring out the letter can still be part of any other word (words can cross and overlap). When all words from list are found and scored out there are several remaining letters. These letters, read in rows, create the secret word. The words can be found in all eight directions, including diagonal directions. 

It is clear that KOKODáKH has to bring some innovation into this game. The new rule says that the word can “jump over” the array boundary and continue on the opposite side. Upper row is thus next to the bottom row and the left collum is next to the right one. If we number the rows with numbers 0 till R-1 and collums with numbers 0 till S-1, we can describe each field in the array by the coordinates. For example (0,0) is the upper left corner. Word beginning on the position (x,y) can be created by succesion of characters with coordinates (x,y), ((x+i+R) mod R, (y+j+S) mod S), ((x+2i+R) mod R, (y+2j+S) mod S) and so on. The i and j can be substitued by numbers -1, 0 and +1, but they cannot be both zero at the same time. 

Input

The input consists of Z assignments. The number of them is given by the single positive integer Z appearing on the first line of input. The assignements follow. Each assignement consists of array filled with letters, and the list of words which should be found in the array. The description of the array begins with the line containing two integers R and S separated by space 1 <= R,S <= 200. R is the number of rows in the array, S is the number of collumns. The R lines follows, each line constist of exactly S lowercase letters (a trough z). The next line is the integer K (0 <= K <= 1000) determining the number of words to be found out in the puzzle. The K lines follow. On each line, there is one word. The maximum length of the word is 20 characters. The word may not appear in the array and it can appear there several times. In this case all appearences are scored out. Words in the list can repeat.

Output

The program prints one line for each assignement. On this line there will be all letters from word puzzle which remained in the array after scoring out all the words that appeared on the list. The letters are not separated and they are lined up in order in which they appeared in the array in row major order. At the end of the string, there is the newline character. If there are no remaining letters after scoring out all words, the program prints out empty line.

Sample Input

1
3 7
kroksun
pranyra
cmakrom
7
syr
kra
kroksunkrok
pranyr
rak
mak
makro

Sample Output

acm

Source

CTU Open 1999
将k个字符串存到trie树里。对枚举每个字符作为起点,往8个方向都检查一次是否匹配trie树立的字符串,若匹配则消去

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

#define rep(i,n) for(int i=0; i<n; i++)
int r,s;
char g[201][201];
int used[201][201];
int dx[3]={-1,0,1},dy[3]={-1,0,1};
const int tk=26, tb='a';
int top, tree[200000][tk+1];
void init()
{
    top=1;
    memset(tree[0], 0, sizeof(tree[0]));
}


void insert(char *s, int rank=1)
{
    int rt,nxt;
    for(rt=0; *s; rt=nxt, ++s){
        nxt=tree[rt][*s-tb];
        if(0==nxt){
            tree[rt][*s-tb]=nxt=top;
            memset(tree[top], 0, sizeof(tree[top]));
            top++;
        }
    }
    tree[rt][tk]=rank;
}

void prefix(int &x, int &y, int dx, int dy)
{
    int rt=0,lv,len=0;
    int nx=x,ny=y;
    int flag=1;
    for(lv=0; g[nx][ny]; nx=(nx+dx+r)%r,ny=(ny+dy+s)%s, ++lv){
        rt=tree[rt][g[nx][ny]-tb];
        if(tree[rt][tk]) len=lv+1;
        if(!rt) break;
    }

    for(int i = 0,nx=x,ny=y; i<len; i++,nx=(nx+dx+r)%r,ny=(ny+dy+s)%s)
        used[nx][ny]=1;
}



char str[25];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        init();
        memset(used, 0, sizeof(used));
        scanf("%d%d", &r, &s);
        rep(i,r)
        scanf("%s", g[i]);

        int k;
        scanf("%d",&k);
        while(k--){
            scanf("%s", str);
            insert(str,1);
        }
        rep(x,r) rep(y,s){
          if(!tree[0][g[x][y]-tb]) continue;
          rep(i,3) rep(j,3){
            if(!dx[i] && !dy[j]) continue;
            prefix(x, y, dx[i], dy[j]);
         }
        }

        rep(x,r)rep(y,s)
            if(!used[x][y])
                putchar(g[x][y]);
        putchar('\n');
    }
}

    原文作者:Trie树
    原文地址: https://blog.csdn.net/HTT_H/article/details/45045829
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞