• [poj] 1204 Word Puzzles || AC自动机


    原题

    给个X*Y的字符串矩阵,W个询问,对每个询问输出这个串出现的位置及方向,共有8个方向,顺时针开始分别用A~H表示

    AC自动机的板子题。
    对于待匹配串建一个自动机,然后从矩阵的四周分别沿八个方向跑,找到一个串的时候就记录答案,但不能退出。

    另:方向要找好啊!!

    #include<cstdio>
    #include<cstring>
    #define N 1010
    using namespace std;
    int x,y,n,ansx[N],ansy[N],d[N],l[N];
    //int dx[10]={0,0,1,1,1,0,-1,-1,-1},dy[10]={0,1,1,0,-1,-1,-1,0,1};
    int dx[10]={0,-1,-1,0,1,1,1,0,-1},dy[10]={0,0,1,1,1,0,-1,-1,-1};
    char t[N][N],s[N],r[10]=" ABCDEFGH";
    struct hhh
    {
        int data;
        hhh *child[26],*fail;
        hhh()
    	{
    	    fail=NULL;
    	    data=0;
    	    for (int i=0;i<26;i++) child[i]=NULL;
    	}
    };
    hhh *root=new hhh;
    hhh *now,*tmp;
    hhh* q[100*1000+10];
    
    void add(int x)
    {
        now=root;
        for (int i=1;i<=l[x];i++)
        {
    	if (now->child[s[i]-'A']==NULL)
    	    now->child[s[i]-'A']=new hhh;
    	now=now->child[s[i]-'A'];
        }
        now->data=x;
    }
    
    void bfs()
    {
        int l=0,r=0;
        root->fail=root;
         for (int i=0;i<26;i++)
        {
    	if (root->child[i]==NULL)
    	    root->child[i]=root;
    	else
    	    root->child[i]->fail=root,q[r++]=(root->child[i]);
        }
        while (r!=l)
        {
    	hhh* nw=q[l++];
    	for (int i=0;i<26;i++)
    	{
    	    if (nw->child[i])
    	    {
    		now=nw->child[i];
    		if (now!=root) q[r++]=now;
    		if (now->fail==NULL) now->fail=nw->fail->child[i];
    	    }
    	    else nw->child[i]=nw->fail->child[i];
    	    if (nw->data==0 && nw->fail->data)
    		nw->data=nw->fail->data;
    	}
        }
    }
    
    void find(int a,int b,int i)
    {
        now=root;
        while (1)
        {
    	if (a<=0 || a>x) break;
    	if (b<=0 || b>y) break;
    	now=now->child[t[a][b]-'A'];
    	tmp=now;
    	while (tmp->data)
    	{
    	    int tp=tmp->data;
    	    ansx[tp]=a-dx[i]*(l[tp]-1);
    	    ansy[tp]=b-dy[i]*(l[tp]-1);
    	    d[tp]=i;
    	    tmp=tmp->fail;
    	}
    	a+=dx[i];
    	b+=dy[i];
        }
    }
    
    int main()
    {
        scanf("%d%d%d",&x,&y,&n);
        for (int i=1;i<=x;i++)
    	scanf("%s",t[i]+1);
        for (int i=1;i<=n;i++)
        {
    	scanf("%s",s+1);
    	l[i]=strlen(s+1);
    	add(i);
        }
        bfs();
        for (int i=1;i<=8;i++)
        {
    	for (int j=1;j<=x;j++)
    	{
    	    find(j,1,i);
    	    find(j,y,i);
    	}
    	for (int j=1;j<=y;j++)
    	{
    	    find(1,j,i);
    	    find(x,j,i);
    	}
        }
        for (int i=1;i<=n;i++)
    	printf("%d %d %c
    ",ansx[i]-1,ansy[i]-1,r[d[i]]);
        return 0;
    }
    
  • 相关阅读:
    hdu3746Cyclic Nacklace(KMP)
    hdu2087剪花布条(KMP)
    cellspacing cellpadding
    3行3列表格 table实现,div+css实现
    自动办公系统
    (转载)互联网协议入门(二)
    (转载)互联网协议入门(一)
    去掉考勤
    第二次装OA系统
    Windows 7系统下局域网文件共享设置方法
  • 原文地址:https://www.cnblogs.com/mrha/p/7992162.html
Copyright © 2020-2023  润新知