题目大意:
考虑两个n位的十进制正整数A和B,都没有前导0。我们需要找到两个最近的靠近A的n位数(第一个比A大或与A相等,第二个严格比A小),使得它们的十进制表示是B中所有数字的某个排列。
对于给定的A和B,写一个程序closest找到这些“最靠近A”的数字,或者判断它们中的一个不存在,不存在则输出0。
题解:
对于>=A且最小的数
对于一个数,我们肯定是优先它每一位是等于的情况,如果不行,就进一步枚举,如果当前的答案ans,
找到了第i位:
那么 i-1前如果是完全等于N的前i-1位,则这一位只能从n[i]~9去找,否则就从0~9去找。
同理,
对于
var
num:array ['0'..'9'] of longint;
i:longint;
n,m:string;
flag:boolean;
procedure dfs(dep:longint;ans:string;d:boolean);
var
i,j,k:char;
begin
if dep>length(n)
then begin
if ans>=n then exit;
writeln(ans);
flag:=true;
exit;
end;
if d then j:=n[dep]
else j:='9';
if dep=1 then k:='1'
else k:='0';
for i:=j downto k do
if num[i]<>0 then
begin
dec(num[i]);
if (i=n[dep]) and (d)
then dfs(dep+1,ans+i,true)
else dfs(dep+1,ans+i,false);
inc(num[i]);
if flag then break;
end;
end;
procedure find(dep:longint;ans:string;d:boolean);
var
i,j,k:char;
begin
if dep>length(n)
then begin
if ans<n then exit;
writeln(ans);
flag:=true;
exit;
end;
if d then j:=n[dep]
else j:='0';
if dep=1 then
if j='0' then j:='1';
for i:=j to '9' do
if num[i]<>0 then
begin
dec(num[i]);
if (i=n[dep]) and (d)
then find(dep+1,ans+i,true)
else find(dep+1,ans+i,false);
inc(num[i]);
if flag then break;
end;
end;
begin
readln(n);
readln(m);
for i:=1 to length(m) do inc(num[m[i]]);
flag:=false;
find(1,'',true);
if not(flag) then writeln('0');
flag:=false;
dfs(1,'',true);
if not(flag) then writeln('0');
end.