1. 程式人生 > >RK(字串雜湊)

RK(字串雜湊)

type an=array[0..510]of boolean;
hash=record
	f1,f2,po,va:longint;
end;
var m,i,j,k,a,b,c,n,q,p,d:longint;
v:array[0..30010]of an;
ch:char;
p1,p2:longint;
h:array[0..51138]of hash;
cc,err:array[0..30010]of longint;
jud:boolean;
co:longint;
bi:an;
procedure hashpush(e1,e2,po:longint);
var i:longint;
begin
	i:=e1;
	while((h[i].f1<>e1)or(h[i].f2<>e2))and(h[i].po<>0) do i:=(i+1)mod p1;
	if(h[i].po=0)then begin
		h[i].f1:=e1;h[i].f2:=e2;
		h[i].po:=po;
		h[i].va:=1;
	end else begin
		inc(h[i].va);
	end;
end;

function hashask(e1,e2:longint):longint;
var i,j:longint;
begin
	i:=e1;
	while((h[i].f1<>e1)or(h[i].f2<>e2))and(h[i].po<>0) do i:=(i+1)mod p1;
	exit(h[i].va);
end;

procedure radixsort();
var i,j,k,po,fa,fb:longint;
	a,b:array[0..30010]of longint;	
begin
	po:=m;
	for i:=1 to n do cc[i]:=i;
	for j:=m downto 1 do begin
		fa:=0;fb:=0;
		for i:=1 to n do begin
			if v[cc[i]][j]=true then begin
				inc(fa);
				a[fa]:=cc[i];
			end else begin
				inc(fb);
				b[fb]:=cc[i];
			end;
		end;
		for i:=1 to fb do cc[i]:=b[i];
		for i:=1 to fa do cc[i+fb]:=a[i];
	end;
end;

begin
	p1:=51137;p2:=10001531;
	readln(n,m,p,q);
	for i:=1 to n do begin
		a:=0;b:=0;
		for j:=1  to m do begin
			read(ch);
			if(ch='Y')then begin 
				v[i][j]:=true;
				a:=(a*2+1)mod p1;
				b:=(b*2+1)mod p2;
			end else begin
				v[i][j]:=false;
				a:=a*2 mod p1;
				b:=b*2 mod p2;
			end;
		end;
		readln;
		hashpush(a,b,i);
	end;
	a:=0;b:=0;
	radixsort();
	{	for i:=1 to n do begin
		for j:=1 to m do if v[cc[i]][j] then  write('Y') else write('N');
		writeln;
	end;}
	if (p<>0) then begin
		for i:=1 to n do begin
			a:=0;b:=0;
			for j:=1 to m do begin
				if v[cc[i]][j] then begin
					a:=a*2+1;
					b:=b*2+1;
					a:= a mod p1;
					b:=b mod p2;
				end else begin
					a:=a*2 mod p1;b:=b*2 mod p2;
				end;

			end;
			k:=hashask(a,b);
			if k=p then begin
				a:=0;b:=0;
				for j:=1 to m do begin
					if v[cc[i]][j] then begin
						a:=a*2;b:=b*2;
					end else begin
						a:=a*2+1;b:=b*2+1;
					end;
					a:=a mod p1;b:=b mod p2;
				end;		
				k:=hashask(a,b);
				if k=q then begin
					for k:=1 to m do if v[cc[i]][k] then write('Y') else write('N');
					exit;
				end;
			end;
		end;
	end else begin
		if q=0 then begin
			a:=0;b:=0;
			fillchar(bi,sizeof(bi),0);
			while(true)do begin
				inc(a);inc(b);
				a:=a mod p1;b:=b mod p2;
				for i:= m downto 0 do begin
					if bi[i]=false then break else bi[i]:=false;
				end;
				if i=0 then break;
				bi[i]:=true;
				if hashask(a,b)=0 then begin
					c:=0;d:=0;
					for i:=1 to m do begin
						if not bi[i] then begin
							c:=c*2+1;
							d:=d*2+1;
						end else begin 
							c:=c*2;
							d:=d*2;
						end;
						c:=c mod p1;d:=d mod p2;
					end;
					if hashask(c,d)=0 then begin
						for i:=1 to m do if bi[i] then write('Y') else write('N');
						exit;
					end;
				end;
			end;
		end else begin
			for i:=n downto 1 do begin
				a:=0;b:=0;
				for j:=1 to m do begin
					if v[cc[i]][j] then begin
						a:=a*2+1;
						b:=b*2+1;
					end else begin
						a:=a*2;b:=b*2;
					end;
					a:=a mod p1;b:=b mod p2;
				end;
				if hashask(a,b)=q then begin
					for j:=1 to m do begin
						if not v[cc[i]][j] then begin
							a:=a*2+1;
							b:=b*2+1;
						end else begin
							a:=a*2;b:=b*2;
						end;
						a:=a mod p1;b:=b mod p2;
					end;	
					if hashask(a,b) = p then begin
						for j:=1 to m do if v[cc[i]][j] then write('N') else write('Y');
						exit;
					end;
					
				end;
			end;
		end;
	end;
	writeln(-1);
end.