搜索与回溯练习(三)
搜索算法_字符串的序号
AYYZOJ p1457
COGS p819
题意就是:把组成该字符串的所有字符,重新进行任意组合,然后把结果按字典序进行排列,找出原字符串所在的位置。这应该是用排列组合的思路进行解题,方法就是从第一位字符开始进行循环判断,根据他在所有字符中所处的位置,来判断排在他前面的字符串的数量。
1 var 2 s:string; 3 p:longint; 4 a:array['a'..'z'] of integer; 5 st:string; 6 7 procedure Init; 8 var c:char; 9 i:integer; 10 begin 11 readln(s); 12 for i:=1 to length(s) do 13 begin 14 c:=s[i]; 15 inc(a[c]); 16 end; 17 end; 18 19 procedure DFS(d:integer); 20 var c:char; 21 begin 22 if d>length(s) then 23 begin 24 inc(p); 25 if s=st then 26 begin 27 writeln(p); 28 halt; 29 end; 30 end else 31 for c:='a' to 'z' do 32 if a[c]>0 then 33 begin 34 dec(a[c]); 35 st:=st+c; 36 DFS(d+1); 37 st:=copy(st,1,d-1); 38 inc(a[c]); 39 end; 40 end; 41 42 begin 43 Init; 44 DFS(1); 45 end.
1 program p1457; 2 var 3 i,l,n:longint; 4 s,s1:string; 5 a:array['a'..'z'] of longint; 6 procedure Search(k:longint); 7 var c:char; 8 begin 9 for c:='a' to 'z' do 10 if a[c]>0 then begin 11 dec(a[c]); 12 s1:=s1+c; 13 if k=l then begin 14 inc(n); 15 if s1=s then begin writeln(n); halt; end; 16 end 17 else Search(k+1); 18 inc(a[c]); 19 delete(s1,k,1); 20 end; 21 end; 22 begin 23 assign(input,'stringnum.in'); 24 reset(input); 25 assign(output,'stringnum.out'); 26 rewrite(output); 27 readln(s); 28 fillchar(a,sizeof(a),0); 29 l:=length(s); 30 for i:=1 to l do inc(a[s[i]]); 31 s1:=''; 32 Search(1); 33 end.
1 program cogs819; 2 var 3 s:string; 4 a:array['a'..'z']of integer; 5 i,ans:integer; 6 procedure dfs(len:integer;x:string); 7 var 8 i:char; 9 begin 10 if len=length(s) then 11 begin 12 inc(ans); 13 if x=s then begin 14 writeln(ans);halt;end; 15 exit; 16 end; 17 for i:='a' to 'z' do 18 if a[i]>0 then begin 19 dec(a[i]); 20 dfs(len+1,x+i); 21 inc(a[i]); end; 22 end; 23 begin 24 assign(input,'stringnum.in');reset(input); 25 assign(output,'stringnum.out');rewrite(output); 26 readln(s); 27 fillchar(a,sizeof(a),0); 28 for i:=1 to length(s) do inc(a[s[i]]); 29 dfs(0,''); 30 close(input);close(output); 31 end.
其实简单的搜索题写出来思想都一样,结构写出来一模一样。
这么简单的题对于初学搜索的我,还是交了3遍:
第一次是因为我把所有排列顺序都求了出来再一一比对,耗时不少
第二次是因为删去全部求出后,忘记在求得答案时加个halt。
写的时候还担心数据范围(integer)不够,囧。。