2570. 【NOIP2011模拟9.17】数字生成游戏 (Standard IO)

38 篇文章 0 订阅
7 篇文章 0 订阅

Description

小明完成了这样一个数字生成游戏,对于一个不包含0的数字s来说,有以下3种生成新的数的规则:
1.将s的任意两位对换生成新的数字,例如143可以生成341,413,134;
2.将s的任意一位删除生成新的数字,例如143可以生成14,13,43
3.在s的相邻两位之间s[i],s[i + 1]之间插入一个数字x,x需要满足s[i]<x<s[i + 1],即比它插入位置两边的数小。例如143可以生成1243,1343,但是不能生成1143,1543等。
现在小明想知道,在这个生成法则下,从s开始,每次生成一个数,可以用新生成的数生成另外一个数,不断生成直到生成t至少需要多少次生成操作。
另外,小明给规则3又加了一个限制,即生成数的位数不能超过初始数s的位数。若s是143,那么1243与1343都是无法生成的;若s为1443,那么可以将s删除4变为143,再生成1243或1343。

Input

输入文件gen.in的第一行包含1个正整数,为初始数字s。
第2行包含一个正整数m,为询问个数。
接下来m行,每行一个整数t(t不包含0),表示询问从s开始不断生成数字到t最少要进行多少次操作。任两个询问独立,即上一个询问生成过的数到下一个询问都不存在,只剩下初始数字s。

Output

输出文件gen.out包括m行,每行一个正整数,对每个询问输出最少操作数,如果无论也变换不成,则输出-1。

Sample Input

143
3
134
133
32

Sample Output

1
-1
4

【样例说明】

143->134
133无法得到
143->13->123->23->32

【数据规模与约定】

对于20%的数据,s<100;
对于40%的数据,s<1000;
对于40%的数据,m<10;
对于60%的数据,s<10000;
对于100%的数据,s<100000,m≤50000。

题解

乍一看很难,但其实数字只有5位,搜索,枚举,BFS。

代码

var
  a,b:array[0..100000] of longint;
  len,x,h,t:longint;
  s:string;
procedure ff1;
var
  i,j,n,l:longint;
  y,m:string;
begin
  str(x,y);
  l:=length(y);
  for i:=1 to l-1 do
    for j:=i+1 to l do
      if i<>j then
        begin
          m:=copy(y,1,i-1)+y[j]+copy(y,i+1,j-i-1)+y[i]+copy(y,j+1,l);
          val(m,n);
          if m='' then exit;
          if b[n]<0 then
            begin
              b[n]:=b[x]+1;
              inc(t);
              a[t]:=n;
            end;
        end;
end;
procedure ff2;
var
  i,j,n,l:longint;
  y,m:string;
begin
  str(x,y);
  l:=length(y);
  if l=1 then exit;
  for i:=1 to l do
    begin
      m:=copy(y,1,i-1)+copy(y,i+1,l);
      if m='' then exit;
      val(m,n);
      if b[n]<0 then
        begin
          b[n]:=b[x]+1;
          inc(t);
          a[t]:=n;
        end;
    end;
end;
procedure ff3;
var
  i,j,n,k,g,l:longint;
  y,m,z:string;
begin
  str(x,y);
  l:=length(y);
  if l>=len then exit;
  if l=1 then exit;
  for i:=1 to l-1 do
    begin
      val(y[i],k);val(y[i+1],g);
      for j:=k+1 to g-1 do
        begin
          str(j,z);
          m:=copy(y,1,i)+z+copy(y,i+1,l);
          val(m,n);
          if b[n]<0 then
            begin
              b[n]:=b[x]+1;
              inc(t);
              a[t]:=n;
            end;
        end;
    end;
end;
var
  n,m,c,i:longint;
begin
  readln(s);
  val(s,n);
  len:=length(s);
  for i:=0 to 100000 do b[i]:=-1;
  b[n]:=0;
  t:=1;
  a[1]:=n;
  while h<t do
    begin
      inc(h);x:=a[h];
      ff1;
      ff2;
      ff3;
    end;
  readln(m);
  for i:=1 to m do
    begin
      readln(c);
      writeln(b[c]);
    end;
end.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值