`
java-mans
  • 浏览: 11415190 次
文章分类
社区版块
存档分类
最新评论

POJ 1204 AC自动机

 
阅读更多

题目就是给出了一个矩阵,由大写字母构成,然后让你查找某些单词在矩阵中出现的位置

出现的方式可能有8种,从某个位置往北连续的字符串,往东北,东........八个方向的只要有满足的 就可以

最后输出位置和方向,然后往北的输出时为A,东北的是B,依次顺时针类推

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#define eps 1e-5
#define MAXN 1111
#define MAXM 222200
#define INF 1000000000
using namespace std;
int e, cnt, L, C, W;
char s[MAXN][MAXN];
bool vis[MAXN];
int ansx[MAXN], ansy[MAXN], len[MAXN];
int loc[MAXN];
int tx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, ty[8] = {0, 1, 1, 1, 0, -1, -1, -1};
char dic[] = "ABCDEFGH";
char tmp[MAXN];
struct Trie
{
    int next[26];
    int fail, id;
    void init ()
    {
        memset(next, 0, sizeof(next));
        fail = -1;
        id = 0;
    }
} trie[MAXM];
void make_trie (char *str, int id)
{
    int i = 0, index, u = 0;
    while(str[i])
    {
        index = str[i] - 'A';
        if(!trie[u].next[index]) trie[u].next[index] = ++e;
        u = trie[u].next[index];
        i++;
    }
    trie[u].id = id;
}
int q[MAXM];
void make_ac_automation()
{
    int i, j;
    int h = 0,  t = 0;
    q[t++] = 0;
    while(h < t)
    {
        int u = q[h++];
        for(i = 0; i < 26; i++)
            if(trie[u].next[i])
            {
                int v = trie[u].next[i];
                for(j = trie[u].fail; j != -1; j = trie[j].fail)
                    if(trie[j].next[i])
                    {
                        trie[v].fail = trie[j].next[i];
                        break;
                    }
                if(j == -1) trie[v].fail = 0;
                q[t++] = v;
            }
    }
}
void match(int x, int y, int k)
{
    int u = 0, index;
    while(s[x][y])
    {
        index = s[x][y] - 'A';
        while(!trie[u].next[index] && u != 0) u = trie[u].fail;
        u = trie[u].next[index];
        if(u == -1) u = 0;
        int v = u;
        while(v != 0 && trie[v].id != -1)
        {
            if(trie[v].id > 0 && !vis[trie[v].id])
            {
                cnt++;
                vis[trie[v].id] = 1;
                ansx[trie[v].id] = x - (len[trie[v].id] - 1) * tx[k];
                ansy[trie[v].id] = y - (len[trie[v].id] - 1) * ty[k];
                loc[trie[v].id] = k;
                if(cnt == W) return;
            }
            trie[v].id = -1;
            v = trie[v].fail;
        }
        x += tx[k], y += ty[k];
    }
}
int main()
{
    for(int i = 0; i < MAXM; i++) trie[i].init();
    scanf("%d%d%d", &L, &C, &W);
    for(int i = 1; i <= L; i++) scanf("%s", s[i] + 1);
    for(int i = 1; i <= W; i++)
    {
        scanf("%s", tmp);
        make_trie(tmp, i);
        len[i] = strlen(tmp);
    }
    make_ac_automation();
    for(int i = 1; i <= C; i++)
        match(L, i, 0);//A
    for(int i = 1; i <= L; i++)
        match(i, 1, 1);//B
    for(int i = 1; i <= C; i++)
        match(L, i, 1);//B
    for(int i = 1; i <= L; i++)
        match(i, 1, 2);//C
    for(int i = 1; i <= C; i++)
        match(1, i, 3);//D
    for(int i = 1; i <= L; i++)
        match(i, 1, 3);
    for(int i = 1; i <= C; i++)
        match(1, i, 4);//E
    for(int i = 1; i <= L; i++)
        match(i, C, 5);//F
    for(int i = 1; i <= C; i++)
        match(1, i, 5);
    for(int i = 1; i <= L; i++)
        match(i, C, 6);//G
    for(int i = 1; i <= C; i++)
        match(L, i, 7);//H
    for(int i = 1; i <= L; i++)
        match(i, C, 7);
    for(int i = 1; i <= W; i++)
        if(vis[i]) printf("%d %d %c\n", ansx[i] - 1, ansy[i] - 1, dic[loc[i]]);
    return 0;
}


分享到:
评论

相关推荐

    poj1007AC代码

    poj1007 AC代码 0MS过题写法 不过是个水题 哈哈哈哈

    poj 3674 AC代码

    poj 3674 SuperAssassin 的AC代码

    我的Poj里的一些AC代码

    我的Poj里的一些AC代码

    poj3586AC代码

    poj3586,推导题,可以推导出一个贪心的结论,具体看代码。

    poj2342AC代码

    poj2342,树形dp,dp[i][0]表示i不参加party,其下属(包括非直接下属)能得到的最优值。dp[i][1]表示i参加的其下属和他能得到的最优值。

    poj acm的AC解题报告

    http://acm.pku.edu.cn/JudgeOnline/ acm的AC解题报告

    POJ 300多题AC代码

    一年多的ACM经历,做了这300多题,希望对大家有帮助!!

    poj2343AC代码

    poj2343,规模比较小,只有50,搜索即可,具体看代码。

    POJ 1328 java AC

    POJ 1328 java做!雷达问题!java版本!AC答案~

    poj1157ac代码

    复杂度n^2 b

    poj2628AC代码

    poj2628,判断需要锯掉多少长度才能使得桌子平衡,可以知道至少需要三根相同长度且是最长的桌腿。按桌腿长度排序,然后判断是否可以保持平衡(所有桌腿不同在圆心的一边即可)

    poj1125原创AC代码

    poj1125原创AC代码,用的是folyd算法,求出所有点之间的最短路径,再以此求出每个点到其他点的最长路径。。。

    poj2340AC代码

    poj2340,模拟题,使用两个优先队列模拟即可。

    poj2605AC代码

    poj2605,简单推导题。分几种情况讨论即可。

    poj2599AC代码

    poj2599,简单dfs可以过此题,按顺序搜到任意可行解即可。

    北大poj AC源码1600个(C或C++)

    北大poj AC源码1600个(C或C++)

    poj ac题目代码

    1000 1003 1004 1005 1006 1008 1012 1028 1036 1045 1046 1047 1087 1163 1183 1207 1218 1247 1269 1298 1306 1316 1326 1331 1338 1401 1423 1450 1455 1477 1488 1503 1504 1517 1519 1528 1543 1547 1552 1555 ...

    POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类

    POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类

    Poj1006题目ac代码

    解决poj1006问题

    WOJ1204代码解题思路2

    用栈来解决。设置两个数组,其中一个是要求输入的数组a。另一个数组b用于保存含有相同的元素的序列。 先把数组的第一个值压入栈底,在看第二个数是不是和第一个数是相同的。如果相同则进栈,否则的话栈底元素出栈...

Global site tag (gtag.js) - Google Analytics