读入后把不满足条件的单词去掉然后O(n^2)枚举就好了。
代码
{ ID: ymwbegi1 PROG: lgame LANG: PASCAL } const num:array['a'..'z'] of longint=(2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2 ,4,6,6,7,5,7); var s,w:string; i,j,k,ans,f1,n,len:longint; a,f:array[0..4000] of string; l,b:array[1..4000] of longint; v,v1:array['a'..'z'] of longint; flag:boolean; begin assign(input,'lgame.in'); assign(output,'lgame.out'); reset(input); rewrite(output); readln(s); close(input); len:=length(s); for i:=1 to len do inc(v[s[i]]); assign(input,'lgame.dict'); reset(input); readln(w); while w<>'.' do begin flag:=true; v1:=v; for i:=1 to length(w) do if v1[w[i]]=0 then begin flag:=false; break; end else dec(v1[w[i]]); if flag then begin inc(n); a[n]:=w; l[n]:=length(w); for i:=1 to l[n] do b[n]:=b[n]+num[w[i]]; end; readln(w); end; close(input); for i:=1 to n do if b[i]>ans then ans:=b[i]; for i:=1 to n-1 do for j:=i+1 to n do if l[i]+l[j]<=len then begin v1:=v; flag:=true; for k:=1 to l[i] do if v1[a[i,k]]=0 then begin flag:=false; break; end else dec(v1[a[i,k]]); for k:=1 to l[j] do if v1[a[j,k]]=0 then begin flag:=false; break; end else dec(v1[a[j,k]]); if (flag)and(b[i]+b[j]>ans) then ans:=b[i]+b[j]; end; writeln(ans); for i:=1 to n do if b[i]=ans then begin inc(f1); f[f1]:=a[i]; end; for i:=1 to n-1 do for j:=i+1 to n do if l[i]+l[j]<=len then begin v1:=v; flag:=true; for k:=1 to l[i] do if v1[a[i,k]]=0 then begin flag:=false; break; end else dec(v1[a[i,k]]); for k:=1 to l[j] do if v1[a[j,k]]=0 then begin flag:=false; break; end else dec(v1[a[j,k]]); if (flag)and(b[i]+b[j]=ans) then begin inc(f1); f[f1]:=a[i]+' '+a[j]; end; end; for i:=1 to f1-1 do for j:=i+1 to f1 do if f[i]>f[j] then begin f[0]:=f[i];f[i]:=f[j];f[j]:=f[0]; end; for i:=1 to f1 do writeln(f[i]); close(output); end.