求ac自动机 pascal模板

2020-06-30 科技 111阅读
POJ1204(AC自动机模板题)
题意:给一个N行长为M的字符串,给你一些需要去匹配的字符串,从任意一个字符串开始可以有八个方向,向上为A,顺时针依次是A——H,问你去匹配的字符串在给你的N*M字符串中的坐标是怎么样的。
代码:
const maxnodes=500000;
var fx:array[1..8] of char=('E','F','G','H','A','B','C','D');
t:array[0..maxnodes,'A'..'Z'] of longint;
f,q,w:array[0..maxnodes] of longint;
e:array[0..1001,0..1001] of char;
s:array[0..1001] of char;
colu,line:array[0..1] of longint;
done:array[0..1001] of boolean;
ans:array[0..1001] of record x,y,f:longint; end;
n,m,num,u,i,j,k,l,r,root,size,x,y,p,li,co,tmp,len:longint;
c:char;
function nx(var x,y:longint; f:longint):char;
begin
case f of
1:dec(x);
2:begin dec(x); inc(y); end;
3:inc(y);
4:begin inc(x); inc(y); end;
5:inc(x);
6:begin inc(x); dec(y); end;
7:dec(y);
8:begin dec(x); dec(y); end;
end;
if (x<1)or(x>n)or(y<1)or(y>m) then exit('!');
exit(e[x,y]);
end;
begin
readln(n,m,num);
line[0]:=1;
line[1]:=n;
colu[0]:=1;
colu[1]:=m;
for i:=1 to n do
begin
for j:=1 to m do read(e[i,j]);
readln;
end;

root:=0;
size:=0;

for i:=1 to num do
begin
len:=0;
while not eoln do
begin
inc(len);
read(s[len]);
end;
p:=root;
for j:=len downto 1 do
begin
c:=s[j];
if t[p][c]=0 then
begin
inc(size);
t[p][c]:=size;
end;
p:=t[p][c];
end;
w[p]:=i;
readln;
end;

l:=0;
r:=0;
for c:='A' to 'Z' do
if t[root][c]<>0 then
begin
inc(r);
q[r]:=t[root][c];
f[q[r]]:=root;
end;
while l begin
inc(l);
u:=q[l];
for c:='A' to 'Z' do
if t[u][c]<>0 then
begin
inc(r);
q[r]:=t[u][c];
p:=f[u];
while (p<>root)and(t[p][c]=0) do p:=f[p];
f[q[r]]:=t[p][c];
end;
end;

for k:=1 to 8 do
for li:=0 to 1 do
for co:=1 to m do
begin
x:=line[li];
y:=co;
p:=root;
c:=e[x,y];
while true do
begin
while (p<>root)and(t[p][c]=0)do p:=f[p];
p:=t[p][c];
tmp:=p;
while tmp<>root do
begin
if (w[tmp]>0)and(not done[w[tmp]]) then
begin
ans[w[tmp]].x:=x;
ans[w[tmp]].y:=y;
ans[w[tmp]].f:=k;
done[w[tmp]]:=true;
end;
tmp:=f[tmp];
end;
c:=nx(x,y,k);
if c='!' then break;
end;
end;
for k:=1 to 8 do
for co:=0 to 1 do
for li:=1 to n do
begin
x:=li;
y:=colu[co];
p:=root;
c:=e[x,y];
while true do
begin
while (p<>root)and(t[p][c]=0)do p:=f[p];
p:=t[p][c];
tmp:=p;
while tmp<>root do
begin
if (w[tmp]>0)and(not done[w[tmp]]) then
begin
ans[w[tmp]].x:=x;
ans[w[tmp]].y:=y;
ans[w[tmp]].f:=k;
done[w[tmp]]:=true;
end;
tmp:=f[tmp];
end;
c:=nx(x,y,k);
if c='!' then break;
end;
end;
for i:=1 to num do writeln(ans[i].x-1,' ',ans[i].y-1,' ',fx[ans[i].f]);
end.
声明:你问我答网所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系fangmu6661024@163.com