【Hash,little baby~】查单词
【题目描述】
全国英语四级考试就这样如期来了,可是小y依然没有做好充分准备。为了能够大学毕业可怜的小y决定作弊。
小y费尽心机,在考试的时候夹带了一本字典进考场,但是现在的问题是,考试的时候可能有很多的单词要查,小y能不能来得及呢?
【输入格式】
第一行一个整数N,表示字典中一共有多少个单词(N<=10000)。
接下来每两行表示一个单词,其中:
第一行是一个长度<=100的字符串,表示这个单词,全部小写字母,单词不会重复。
第二行是一个整数,表示这个单词在字典中的页码。
接下来是一个整数M,表示要查的单词数(M<=10000)。
接下来M行,每行一个字符串,表示要查的单词,保证在字典中存在。
【输出格式】
M行,每行一个整数,表示第I个单词在字典中的页数。
【输入样例】
2
scan
10
word
15
2
scan
word
【输出样例】
10
15
网上流传的解法都是Hash,可是打冲突处理太麻烦了。其实用二叉排序树解这道题也是一种不错的方法。
我费尽心机自创了一个诡异的Hash函数,骗过了4组~
参考代码(伪Hash,40)
scan
1 program scanwords;
2 var
3 h:array[1..50000]of longint;
4 s:string;
5 n,m,i:longint;
6 function hash(s:string):longint;
7 var
8 i,k:integer;
9 mul:longint;
10 begin
11 mul:=1;
12 for i:=1 to length(s) do
13 begin
14 k:=round(sqrt(ord(s[i]))*99);
15 mul:=round(mul*k);
16 mul:=mul mod 49999;
17 end;
18 exit(mul);
19 end;
20 begin
21 readln(n);
22 for i:=1 to n do
23 begin
24 readln(s);
25 readln(m);
26 h[hash(s)]:=m;
27 end;
28 readln(n);
29 for i:=1 to n do
30 begin
31 readln(s);
32 writeln(h[hash(s)]);
33 end;
34 end.
其实朴素的二叉排序树是很容易退化的~但是数据比较弱…
参考代码(二叉排序树,100):
1 program scanwords;
2 type l=record
3 s:string;
4 l,r,p:longint;
5 end;
6 var
7 a:array[1..10000]of l;
8 i,j:longint;
9 n,m,t:longint;
10 ss:string;
11 f:boolean;
12 begin
13 readln(n);
14 for i:=1 to n do
15 begin
16 readln(a[i].s);
17 readln(a[i].p);
18 t:=1;
19 while i<>1 do
20 begin
21 if a[i].s>a[t].s then
22 begin
23 if a[t].r=0 then
24 begin
25 a[t].r:=i;
26 break;
27 end
28 else t:=a[t].r;
29 end;
30 if a[i].s<a[t].s then
31 begin
32 if a[t].l=0 then
33 begin
34 a[t].l:=i;
35 break;
36 end
37 else t:=a[t].l;
38 end;
39 end;
40 end;
41 readln(m);
42 for i:=1 to m do
43 begin
44 f:=false;
45 readln(ss);
46 t:=1;
47 while not f do
48 begin
49 if a[t].s>ss then t:=a[t].l;
50 if a[t].s<ss then t:=a[t].r;
51 if a[t].s=ss then
52 begin
53 writeln(a[t].p);
54 f:=true;
55 end;
56 end;
57 end;
58 end.
(saltless原创,转载请注明出处)