搜索与回溯练习(三)

搜索算法_字符串的序号

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)不够,囧。。

原文地址:https://www.cnblogs.com/vacation/p/5179502.html