8.11 Closest 2574

题目

考虑两个n位的十进制正整数A和B,都没有前导0。我们需要找到两个最近的靠近A的n位数(第一个比A大或与A相等,第二个严格比A小),使得它们的十进制表示是B中所有数字的某个排列。

比如说,假如A=3022并且B=1232,用B的数字我们可以获得以下的4位数字:1223, 1232, 1322, 2123, 2132, 2213, 2231, 2312, 2321, 3122, 3212和3221。最小的比A大或者和A相等的数,且用B中的数字组成的是3122,并且最大的严格比A小的数是2321。如果A=1232而且B=3022,可能的数字是2023, 2032, 2203, 2230, 2302, 2320, 3022, 3202和3220。在用B中数字组成的数中,最小的比A大或与A相等的数是2023,没有比A小的数。

对于给定的A和B,写一个程序closest找到这些“最靠近A”的数字,或者判断它们中的一个不存在。
100%的数据满足:1<=n<=60

题解

好像就是一道模拟,又看起来像一道深搜
错的原因吗?
看成了比A大的严格比A大,比A小的小于等于A
然后刚开始用的是while,不是深搜,实际上当发现不行的时候还是要向前退一步去找答案的

O(n2)

代码

var
  c:char;
  d,z:boolean;
  f:array[0..65]of char;
  s:string;
  n,i:longint;
  t:array[0..10]of longint;

procedure max(g,h:longint);
var
  i:longint;
begin
  if (g>n) and not z then
    begin
      for i:=1 to n do write(f[i]);
      writeln;
      z:=true;
      exit;
    end;
  if z then exit;
  for i:=0 to 9 do
    if ((i>=h) or d ) and (t[i]>0) then
      begin
        if (i=0)and(g=1) then break;
        dec(t[i]);
        if i>h then d:=true;
        f[g]:=chr(i+48);
        max(g+1,ord(s[g+1])-48);
        inc(t[i]);
      end;
end;

procedure min(g,h:longint);
var
  i:longint;
begin
  if (g>n)and d then
    begin
      for i:=1 to n do write(f[i]);
      z:=true;
      exit;
    end;
  if z then exit;
  for i:=9 downto 0 do
    if ((i<=h) or d ) and (t[i]>0)  then
      begin
        if (i=0)and(g=1) then break;
        dec(t[i]);
        if i<h then d:=true;
        f[g]:=chr(i+48);
        min(g+1,ord(s[g+1])-48);
        inc(t[i]);
      end;
end;


begin
  readln(s);
  n:=length(s);
  for i:=1 to n do
    begin
      read(c);
      inc(t[ord(c)-48]);
    end;
  max(1,ord(s[1])-48);
  if not z then writeln('0');
  z:=false;d:=false;
  min(1,ord(s[1])-48);
  if not z then writeln('0');
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值