标签:strlen += 自动机 printf void can queue -- while
把要查询的串都扔进AC自动机,然后暴力check就是了
const int z[10][4]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
int n,m,q;
char s[N][N];
char str[N][N];
int px[N],py[N],dir[N];
namespace AC{
static const int SIZE=1e6+10;
int trie[SIZE][26];
vector <int> End[SIZE];
int fail[SIZE],cnt,vis[SIZE];
int Insert(char *s){
int p=0;
rep(i,0,strlen(s)-1) {
int x=s[i]-‘A‘;
((!trie[p][x])&&(trie[p][x]=++cnt));
p=trie[p][x];
}
//cout<<"Add"<<p<<endl;;
return p;
}
void Build(char s[N][N]){
rep(i,1,q) End[Insert(s[i])].push_back((int)i);
static queue <int> que;
rep(i,0,25) if(trie[0][i]) que.push(trie[0][i]);
while(!que.empty()) {
int u=que.front(); que.pop();
//cout<<u<<endl;
rep(i,0,25) {
int &v=trie[u][i];
if(v) {
fail[v]=trie[fail[u]][i];
que.push(v);
} else v=trie[fail[u]][i];
}
}
}
void dfs(int x,int y,int d,int p) {
//cout<<x<<‘ ‘<<y<<‘ ‘<<d<<‘ ‘<<p<<endl;
p=trie[p][s[x][y]-‘A‘];
for(int j=p; j && !vis[j]; j=fail[j]) {
vis[j]=1;
rep(k,0,End[j].size()-1) {
int t=End[j][k];
px[t]=x,py[t]=y;
dir[t]=d;
}
}
x+=z[d][0],y+=z[d][1];
if(x>=n||y>=m||x<0||y<0) return;
dfs(x,y,d,p);
}
}
using AC::dfs;
int main(){
n=rd(),m=rd(),q=rd();
rep(i,0,n-1) scanf("%s",s[i]);
rep(i,1,q) scanf("%s",str[i]);
AC::Build(str);
rep(i,0,m-1) dfs(n-1,i,0,0);
rep(i,0,n-1) dfs(i,0,1,0); rep(j,0,m-1) dfs(n-1,j,1,0);
rep(i,0,n-1) dfs(i,0,2,0);
rep(i,0,n-1) dfs(i,0,3,0); rep(j,0,m-1) dfs(0,j,3,0);
rep(i,0,m-1) dfs(0,i,4,0);
rep(i,0,m-1) dfs(0,i,5,0); rep(i,0,n-1) dfs(i,m-1,5,0);
rep(i,0,n-1) dfs(i,m-1,6,0);
rep(i,0,n-1) dfs(i,m-1,7,0); rep(j,0,m-1) dfs(n-1,j,7,0);
rep(i,1,q) {
int l=strlen(str[i])-1;
printf("%d %d %c\n",px[i]-l*z[dir[i]][0],py[i]-l*z[dir[i]][1],‘A‘+dir[i]);
}
}
标签:strlen += 自动机 printf void can queue -- while
原文地址:https://www.cnblogs.com/chasedeath/p/12931235.html