题目:给出n个数字0<=n<=3000每个数字位数小于30,较大的可以和较小的共用一把扫把(不一定只有两个数,也就是说可以多个数公用一个扫把),求最少用多少把扫把。
分析:只要给定的数都不相同,那么只需要一把扫把即可。这样,问题就转化成了找出给出的数里重复的次数,重复次数最多的数的个数即为所求。因为每个数字位数小于30位,若用排序的话效率较低,则采用字典树。将每个数当作字符串插入字典树,记录没个数出现的次数,最后查找就好了。注意,04与4都表示4,在插入时不将0插入。
我一开始错的原因是清零字典树时把a1(节电个数)赋值为0,这样是不行的,因为还有一个根节点。
程序:
var ans,n,i,a1:longint; son:array[1..90000,1..10] of longint; s:array[1..90000] of char; a:array[1..90000,1..2] of longint; str:string; procedure insert(x:longint;str:string); var i:longint; begin if str='' then begin inc(a[x,2]); exit; end; for i:=1 to a[x,1] do if s[son[x,i]]=str[1] then begin delete(str,1,1); insert(son[x,i],str); exit; end; inc(a1); inc(a[x,1]); son[x,a[x,1]]:=a1; a[a1,1]:=0; a[a1,2]:=0; s[a1]:=str[1]; delete(str,1,1); insert(a1,str); end; procedure count(x:longint); var i:longint; begin if a[x,2]>ans then ans:=a[x,2]; for i:=1 to a[x,1] do count(son[x,i]); end; begin while not eof do begin readln(n); a[1,1]:=0; a[1,2]:=0; a1:=1; for i:=1 to n do begin readln(str); while (str[1]='0')and(str<>'0') do delete(str,1,1); insert(1,str); end; ans:=0; count(1); writeln(ans); end; end.