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

来源:互联网 发布:淘宝登录异常异地登录 编辑:程序博客网 时间:2024/06/06 00:14

标题的简介:
【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种方案的方法来改变,比如第一种方案就是编号为A\B\D\E四个钟面的数加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.

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

0 0
原创粉丝点击