• 【USACO题库】1.4.2 The Clocks时钟.TJ


    标题的简介:
    【USACO题库】1.4.2 The Clocks——Tj

    https://jzoj.net/junior/#contest/show/1232/11(下文题目描述还是原地址清楚)
    考虑将如此安排在一个 3 x3 行列中的九个时钟:
    |-------| |-------| |-------|

    | | | | | | |

    |—O | |—O | | O |

    | | | | |

    |--------| |-------| |-------|

    A            B            C
    

    |-------| |-------| |-------|

    | | | | | |

    | O | | O | | O |

    | | | | | | | | |

    |-------| |-------| |-------|

    D            E            F
    

    |-------| |-------| |-------|

    | | | | | |

    | O | | O—| | O |

    | | | | | | | |

    |-------| |-------| |-------|

    G            H            I
    

    目标要找一个最小的移动顺序次将所有的指针指向12点。
    下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动。
    选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。
    移动方法 受影响的时钟


    1 ABDE
    2 ABC
    3 BCEF
    4 ADG
    5 BDEFH
    6 CFI
    7 DEGH
    8 GHI
    9 EFHI


    Example
    9 9 12 9 12 12 9 12 12 12 12 12 12 12 12
    6 6 6 5 -> 9 9 9 8-> 9 9 9 4 -> 12 9 9 9-> 12 12 12
    6 3 6 6 6 6 9 9 9 12 9 9 12 12 12
    [但这可能不是正确的方法,请看下面]
    PROGRAM NAME: clocks
    INPUT FORMAT
    第1-3行: 三个空格分开的数字,每个数字表示一个时钟的初始时间,3,6,9,12。
    数字的含意和上面第一个例子一样。
    SAMPLE INPUT (file clocks.in)
    9 9 12
    6 6 6
    6 3 6
    OUTPUT FORMAT
    单独的一行包括一个用空格分开的将所有指针指向12:00的最短移动顺序的列表。
    如果有多种方案,输出那种使的连接起来数字最小的方案。(举例来说5 2 4 6 < 9 3 1 1)。
    SAMPLE OUTPUT (file clocks.out)
    4 5 8 9
    简单来说就是有9个钟,编号为a~i。你要把他的所有的钟指针改成12点,当然有4钟指针方案:3点、6点、9点、12点四种方案。按照:
    1 ABDE
    2 ABC
    3 BCEF
    4 ADG
    5 BDEFH
    6 CFI
    7 DEGH
    8 GHI
    9 EFHI
    这9种方案的方法来改变,比如第一种方案就是编号为ABDE四个钟面的数加3.
    此题很有含金量,所以来讲一讲。
    就是用宽搜的方法去枚举每一个方案,然而会超时或空间炸掉。所以说一说优化:
    优化1:空间与时间的压缩:一般我们都会用一个1到9的数组来储存每个钟面,然后判断各个钟面是不是12点时,就会发现时间瞬间变成了9倍而且空间也十分大。用一个丧心病狂的方法,把每个数字改掉,12点改成4点,9点改成3点,6点改成2点,3点改成1点。例如输入时为
    9 9 12
    6 6 6
    6 3 6
    原来的记录数组就是:9,9,12,6,6,6,6,3,6.变成:3,3,4,2,2,2,2,1,2.
    见证奇迹,把9个数改成9位数,用一个longint来记录:334222212,空间减少9倍,比较时就比较334222212等不等于444444444就OK,时间减少9倍。没算错的话是50分左右,下一个优化。
    优化2:对下面一个优化有用,看起来没用,但是很有用。我们发现,输出答案都是从小到大的方案。完
    优化3:因为输出答案从小到大,我们细心点就发现:每个方案最多用3次,因为用4次是没有意义的。所以我们就每个方案循环3次,就不理了。这两个优化看起来没有屁用,但是实际上这两个优化才是ac的关键之处,可以省x倍(什么鬼)
    程序参考:

    type
            new=record
                    s:string;
                    b:array[1..9] of boolean;
                    a:longint;
            end;
    
    var
            fx:array[1..9,1..5] of longint=((1,2,4,5,0),(1,2,3,0,0),(2,3,5,6,0),(1,4,7,0,0),(2,4,5,6,8),(3,6,9,0,0),(4,5,7,8,0),(7,8,9,0,0),(5,6,8,9,0));
            z:array[1..3,1..9] of longint=((100000000,10000000,1000000,100000,10000,1000,100,10,1),(200000000,20000000,2000000,200000,20000,2000,200,20,2),(300000000,30000000,3000000,300000,30000,3000,300,30,3));
            a:array[1..300000] of new;
            b:array[1..3,1..3] of longint;
            i,j,k,l,n,m,p1,p2,p3,ed:longint;
    
    procedure dg(dep:longint);
    var
            i,j,k,l,n,m,y:longint;
            t:new;
            bz,bz1:boolean;
            s1:string;
    begin
            bz:=true;
            t.a:=a[dep].a;
            fillchar(t.b,sizeof(t.b),true);
            for i:=9 downto 1 do
                    if a[dep].b[i]=false then
                    begin
                            bz:=false;
                            break;
                    end;
            if bz=true then i:=0;
            for j:=i+1 to 9 do
            begin
                    for n:=1 to 3 do
                    begin
                            t.a:=a[dep].a;
                            for l:=1 to 5 do
                            begin
                                    if fx[j,l]<>0 then
                                    begin
                                            k:=t.a div z[1,fx[j,l]] mod 10;
                                            k:=k+n;
                                            if k>4 then
                                            begin
                                                    y:=k mod 4;
                                                    t.a:=t.a-z[1,fx[j,l]]*(k-n)+z[1,fx[j,l]]*y;
                                            end
                                            else t.a:=t.a+z[n,fx[j,l]];
                                    end;
                            end;
                            bz1:=true;
                            if t.a<>444444444 then
                            begin
                                    bz1:=false;
                            end;
                            if bz1=true then
                            begin
                                    s1:=a[dep].s;
                                    for l:=1 to n do
                                    s1:=s1+chr(j+48);
                                    for l:=1 to length(s1) do
                                            write(s1[l],' ');
                                    writeln;
    
                                    halt;
                            end
                            else
                            begin
                                    //if bz=true then
                                    begin
                                            inc(p3);
                                            a[p3].a:=t.a;
                                            for l:=1 to 9 do
                                            a[p3].b[l]:=a[dep].b[l];
                                            a[p3].b[j]:=false;
                                            a[p3].s:=a[dep].s;
                                            for l:=1 to n do
                                            a[p3].s:=a[p3].s+chr(j+48);
                                    end;
                            end;
                    end;
            end;
    end;
    
    begin
            for i:=1 to 3 do
                    for j:=1 to 3 do
                    begin
                            inc(m);
                            read(b[i,j]);
                            if b[i,j]=3 then
                                    a[1].a:=a[1].a*10+1;
                            if b[i,j]=6 then
                                    a[1].a:=a[1].a*10+2;
                            if b[i,j]=9 then
                                    a[1].a:=a[1].a*10+3;
                            if b[i,j]=12 then
                                    a[1].a:=a[1].a*10+4;
    
                                    a[1].b[m]:=true;
                    end;
             p1:=1;p2:=1;p3:=1;
            repeat
                    for i:=p1 to p2 do
                            dg(i);
                    p1:=p2+1;
                    p2:=p3;
            until p1>p2;
    end.
    

    不懂的可以面谈或者发表评论。

    我活在这夜里。无论周围多么黑暗,我都要努力发光!我相信着,终有一天,我会在这深邃的夜里,造就一道最美的彩虹。
  • 相关阅读:
    selenium等待
    selenium断言
    monkey随机测试
    selenium操作元素(键盘和鼠标事件)
    windows10用WMware安装Linux虚拟机详细步骤
    第一个WebDriver脚本
    中文版测试报告
    python3写冒泡排序
    Fiddler设置显式IP地址
    selenium webdriver 常用断言
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148472.html
Copyright © 2020-2023  润新知