美文网首页
2017.07.16【NOIP提高组】模拟赛B组 Digital

2017.07.16【NOIP提高组】模拟赛B组 Digital

作者: mijoe10 | 来源:发表于2017-07-16 11:54 被阅读0次

    原题:

    我们有一个N位数字的电子表,当时间到达10^N-1时,下一秒就归0。下面我们给出数字0 到 9的模拟图。


      
    对于每个数字,相邻两个+之间会有一根电子管,当显示该数字时,这些电子管就会发亮。如上图所示:数字0到9,它们的电子管数量分别是:6、2、 5、 5、 4、 5、 6、 3、 7、 5。  设现在的时刻是X, 那么可以算出该时有多少根电子管是亮的。比如:现在时刻是:99,那么共有5 + 5= 10根电子管是亮的。假如从现在时刻开始,再过Y秒后,时刻显示为Z, 我们的问题是:求最小的Y,使得时刻Z发亮的电子管数量与时刻X发亮的电子管数量相等。如:现在X = 99 ,那么再过Y = 5 秒后, 时刻变成了Z = 04, 而时刻Z发亮的电子管数量 = 6 + 4 = 10。于是Y = 5就是你要求的数。

    输入:

    第一行:一个整数N,表示电子表是10^N进制的。1 <= N <= 15。
    第二行:一个整数X, 表示现在的时刻,可能有前导0。X有N位数字。

    输出:

    一行:最小的整数Y, 表示从现在X时刻开始,再过Y秒,得到的时刻Z发亮的电子管数量与时刻X发亮的电子管数量相等。

    样例输入:

    3
    007

    样例输出:

    11

    样例说明:

    因为数字007有6+6+3 =15根电子管发亮,所以过11秒后,电子表显示数字018时,才能满足发亮的电子管数量相等。018时刻发亮的电子管数量 = 6 + 2 + 7 = 15

    数据说明:

    对于30%数据,N < 7.

    分析:

    对于这道题目,很容易的一的想法就是不断+1,然后判断是否和原数相等,最后相减就是答案,但是这样肯定会超时,因为数字的位数最大有15,那么再来看仔细看题目,我们需要找的就是第一个比x大的并且电子管数量相同的数字(先不考虑超过上限回到0),那么要比x大并且电子管数量相同这要怎么做呢?其实可以发现,从后一位开始改变(改大),看是否可以变成数量相同的,如果当前位不可以,继续同时改后两位,直到可以改变成功。那么如何快速知道是否可以改变呢?需要一个辅助布尔型函数f[len,light,i]表示长度为len(从后往前数),有Light个电子管,且最前面一个数字为i时 是否可以构成。递推而来就可以f[len,light,i]:=f[len,light,i]or f[len-1,light-e[i],j](e是构成数字所需要的电子管数量,j需要枚举,是len-1时的数字)
    举个例子,对于98765 我们先从最后一位开始找,发现不行,然后找后两位,也就是找98766-98799,看是否可以构成相同电子管数量,发现不行,再看第二位9868-9869,还是不行,然后继续,发现988**成立,那么第三个数字就改成8,然后往回推,继续改原先的数字,直到改完,可以递归进行,然后把改变的字符串和之前的字符串变成数字相减就得出答案了
    对于超出n位的那么只需要判断一下,然后把答案字符串清0,从头开始继续上面所做,当然前面部分的答案最后要加上去

    实现:

    const
            e:array[0..9]of longint=(6,2,5,5,4,5,6,3,7,5);
    var
            s,x:string;
            i,j,k,l,n:longint;
            bz:boolean;
            a,b,ans,q:int64;
            f:array[0..17,0..107,0..11]of boolean;
            sum:array[0..17]of longint;
    procedure dg(x,t:longint);
    var
            i:longint;
    begin
            if x=0 then exit;
            for i:=0 to 9 do
                    if f[x,t,i] then break;
            s[n-x+1]:=chr(i+48);
            dg(x-1,t-e[i]);
    end;
    begin
            readln(n);
            readln(x);
            s:=x;
            for i:=0 to 9 do f[1,e[i],i]:=true;
            for i:=2 to n do
                    for j:=0 to 9 do
                            for k:=e[j] to 7*i+1 do
                                    for l:=0 to 9 do f[i,k,j]:=f[i,k,j] or f[i-1,k-e[j],l];
            sum[0]:=0;
            for i:=1 to n do sum[i]:=sum[i-1]+e[ord(s[n-i+1])-48];
            bz:=false;
            for i:=1 to n+1 do
            begin
                    if bz or (i>n) then break;
                    for j:=ord(s[n-i+1])-48+1 to 9 do
                            if f[i,sum[i],j] then
                            begin
                                    bz:=true;
                                    break;
                            end;
            end;
            if bz then
            begin
                    dec(i);
                    s[n-i+1]:=chr(j+48);
                    dg(i-1,sum[i]-e[j]);
                    val(s,a);
                    val(x,b);
                    writeln(a-b);
            end
            else
            begin
                    s:='';
                    for i:=1 to n do s:=s+'0';
                    val(x,b);
                    q:=1;
                    for i:=1 to n do q:=q*10;
                    ans:=q-b;
                    for i:=1 to n+1 do
                    begin
                            if bz or (i>n) then break;
                            for j:=0 to 9 do
                                    if sum[n]-(n-i)*e[0]>=0 then
                                            if f[i,sum[n]-(n-i)*e[0],j] then
                                            begin
                                                    bz:=true;
                                                    break;
                                            end;
                    end;
                    dec(i);
                    s[n-i+1]:=chr(j+48);
                    dg(i-1,sum[n]-(n-i)*e[0]-e[j]);
                    val(s,a);
                    writeln(ans+a);
            end;
    end.
    
    

    相关文章

      网友评论

          本文标题:2017.07.16【NOIP提高组】模拟赛B组 Digital

          本文链接:https://www.haomeiwen.com/subject/sdutkxtx.html