哈希表,在bfs中极为常用,是一种判重方法,优点在于可以用更小的空间记录状态。
以八数码问题为例,在bfs中要判断每一次操作后状态有没重复,如判断123450678这个状态,如果我们开一个范围从10^9到987654321的数组,其中有非常多的空间是用不到的,如222222222这个数是绝对出现不了的,但又在范围中,空间会浪费。
而哈希表,就是一种为了优化这种情况的存在。具体方法:
1、随便取一个数mo,如10000007,用来求下标;
2、建一个数组hash(。。。),要尽可能大,防止爆下标,当然最好算一下下标数。
3、以八数码为例,当123450678这个状态第一次出现时,将他取模,然后以取模后的值为下标存到hash表里,即hash[x mod mo]:=x(n=123450678);
4、如果光那样还不够,假设123450678与213450678这两种情况取模后的值相同的话(当然,这里是举例),那么让x一直变大,直到下标为(x mod mo)的位置数值为空时再赋值;如果是相同的情况的话,他一定会在向后搜时搜到相同情况,这样就可以返回false了。
标程:
const
mo=10000007;
var
n,a:longint;
hash:array[10000..6539412]of longint;
begin
while true do
begin
read(n);
a:=n mod mo;
while(hash[a]<>0)and(hash[a]<>n)do
begin
inc(n);
a:=n mod mo;
end;
if hash[a]=n then
begin
writeln('wrong');
halt;
end else hash[a]:=n;;
end;
end.