SSL P2574 Closest

本文介绍了一种算法,用于寻找给定数值A的最接近的两个n位数,这两个数的十进制表示为另一给定数B的所有数字的一个排列。文章提供了具体的实现流程和伪代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:
考虑两个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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值