COJ 2498 - Boggle AC自动机+DFS

来源:互联网 发布:域名出售 编辑:程序博客网 时间:2024/06/11 03:06

            题意:

                    给了M个单词(M<=100000,单词长度至多为8,单词仅由大写字母构成)..现在给出若干个4*4的字符矩阵(仅含大写字母)..可以从该矩阵任意一个位置出发..不走重复格子的往周围八个方向前进....并且给出了各种长度所能获得的分数.问能获得的最大分数是多少?.至多能走出多少个单词?走出最长的单词是...

            题解:

                    So easy了. 先把这些单词拿来做一个AC自动机...恶心的是空间..我试了好几次才能不ML又不RE..然后就是DFS了..边走边走AC自动机...值得注意的可能有重复的单词..所以要用数组记录一下..


Program:

#include<iostream>#include<stdio.h>#include<string.h>#include<set>#include <stack>#include<queue>#include<algorithm>#include<cmath>#define oo 1000000007#define ll long long#define pi acos(-1.0)#define MAXN 400005 using namespace std;    struct node{      int son[26],fail,w;}P[MAXN];char ss[8],M[4][4];bool had[MAXN],used[4][4];int len[MAXN],T[9]={0,0,0,1,1,2,3,5,11},NUM[MAXN];int F[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};string s[MAXN]; queue<int> Q;void Build_AC(){      int i,h,k;      for (i=0;i<26;i++)          if (P[0].son[i]) Q.push(P[0].son[i]);      while (!Q.empty())      {             h=Q.front(),Q.pop();              for (i=0;i<26;i++)             {                   k=P[h].fail;                   while (k && !P[k].son[i]) k=P[k].fail;                   P[P[h].son[i]].fail=P[k].son[i];                   if (!P[h].son[i]) P[h].son[i]=P[k].son[i];                               else  Q.push(P[h].son[i]);              }      }     }bool cmp(string a,string b){      if (a.length()!=b.length()) return a.length()>b.length();      return a<b;      }void dfs(int y,int x,int h,int step){      int t,k;      if (step>8 || y<0 || x<0 || y==4 || x==4 || used[y][x]) return;       used[y][x]=true;      k=h=P[h].son[M[y][x]-'A'];      while (k) had[P[k].w]=true,k=P[k].fail;      for (t=0;t<8;t++)           dfs(y+F[t][0],x+F[t][1],h,step+1);       used[y][x]=false;}int main(){              int n,i,q,j,t,h,x,ans,num;         memset(P,0,sizeof(P));      scanf("%d",&n);      for (i=1;i<=n;i++) scanf("%s",ss),s[i]=ss;      sort(s+1,s+1+n,cmp);      num=0;      for (t=1;t<=n;t++)      {              len[t]=s[t].length(),NUM[t]=h=0;              for (i=0;i<len[t];i++)              {                       x=s[t][i]-'A';                       if (!P[h].son[x]) P[h].son[x]=++num;                       h=P[h].son[x];              }              if (!P[h].w) P[h].w=t,NUM[t]=1;                      else NUM[P[h].w]++;      }      Build_AC();      scanf("%d",&q);      while (q--)      {              for (i=0;i<4;i++) scanf("%s",M[i]);                   memset(had,false,sizeof(had));              memset(used,false,sizeof(used));              for (i=0;i<4;i++)                  for (j=0;j<4;j++)                    dfs(i,j,0,1);               for (t=1;t<=n;t++)                  if (had[t]) break;              num=ans=0;              for (i=1;i<=n;i++)                 if (had[i]) ans+=NUM[i]*T[len[i]],num+=NUM[i];              printf("%d %s %d\n",ans,s[t].c_str(),num);                       }      return 0;}


原创粉丝点击