天天看点

Trie树 + DFS - CSU 1457 BoggleBoggle  Problem's Link:  http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457

Mean: 

给定n个串,有m个询问。

每个询问给你一个4*4的字符矩阵,你可以在这个字符矩阵中任意字符出发,向四个方向走(已走过的不可重复走),走出一个字符串。

如果n个串中有对应的串和走出的字符串相同,那么需要求出:

1.不同长度的串给了不同的权值,n个串中出现的串的总权值是多少?

2.从出现的字符串中找一个最长的出来,如果有多个,找一个字典序最小的。

3.n个串中总共出现了多少个串?

analyse:

Trie树+DFS.

一开始我是将矩阵的dfs串加入到Trie树中,然后用n个串来匹配树,各种TLE。

后来算了一下时间复杂度,很明显将n个串插入到Trie树中,再用矩阵的dfs串去匹配树,这样更优。

当然这样的话就要自己写字典序的比较函数,也很简单,其他地方没什么坑,写的时候细心一点就行。

Time complexity: O(N+M)

Source code: 

/*

* this code is made by crazyacking

* Verdict: Accepted

* Submission Date: 2015-08-27-13.27

* Time: 0MS

* Memory: 137KB

*/

#include <queue>

#include <cstdio>

#include <set>

#include <string>

#include <stack>

#include <cmath>

#include <climits>

#include <map>

#include <cstdlib>

#include <iostream>

#include <vector>

#include <algorithm>

#include <cstring>

using namespace std;

typedef long long(LL);

typedef unsigned long long(ULL);

const double eps(1e-8);

int score,num;

bool v[5000010],vv[10][10];

int dx[]= {1,1,0,-1,-1,-1,0,1};

int dy[]= {0,1,1,1,0,-1,-1,-1};

int val[]={0,0,0,1,1,2,3,5,11,11,11};

char str[300010][10],Mat[4][5],ans[10],tmp[10];

struct node

{

     node *Next[26];

     int sc,num;

     bool flag;

     node()

     {

           for(int i=0; i<26; ++i) Next[i]=NULL;

           num=0,sc=-1;

     }

} *root;

void Insert(char *s,int id)

     node *p=root;

     int i=0,idx;

     while(s[i])

           idx=s[i]-'A';

           if(p->Next[idx]==NULL)

                 p->Next[idx]=new node();

           p=p->Next[idx];

           ++i;

     p->num=id;

     p->sc=val[strlen(s)];

}

void Matching(char *s)

     int len=strlen(s);

           if(p->Next[idx]==NULL) break;

     if(v[p->num]==false && p->sc!=-1)

           ++num;

           score+=p->sc;

           v[p->num]=true;

           if(num==1 || (strlen(s)>strlen(ans)) || ((strlen(s)==strlen(ans) && strcmp(s,ans)<0)) )

                 memcpy(ans,s,10);

void dfs(int x,int y,int cnt)

     if(cnt>8) return;

     tmp[cnt-1]=Mat[x][y];

     tmp[cnt]='\0';

     Matching(tmp);

     vv[x][y]=true;

     for(int i=0;i<8;++i)

           int xx=x+dx[i];

           int yy=y+dy[i];

           if(vv[xx][yy]!=true && (xx>=0&&xx<4&&yy>=0&&yy<4))

           {

                 vv[x][y]=1;

                 dfs(xx,yy,cnt+1);

                 vv[x][y]=0;

           }

     vv[x][y]=0;

int main()

     ios_base::sync_with_stdio(false);

     cin.tie(0);

     int n,m;

     scanf("%d",&n);

     root=new node();

     for(int i=0; i<n; ++i)

           scanf("%s",str[i]);

           Insert(str[i],i);

     scanf("%d",&m);

     while(m--)

           memset(v,0,sizeof v);

           score=num=0;

           for(int i=0; i<4; ++i)

                 scanf("%s",Mat[i]);

                 for(int j=0; j<4; ++j)

                       dfs(i,j,1);

           printf("%d %s %d\n",score,ans,num);

     return 0;

继续阅读