USACO-Chapter1-Section 1.4-The Clocks (clocks)
【题目描述】
考虑将如此安排在一个 3 x 3 行列中的九个时钟:
|-------| |-------| |-------|
| | | | | | |
|---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 [但这可能不是正确的方法,请看下面]
【输入格式】
第1-3行: 三个空格分开的数字,每个数字表示一个时钟的初始时间,3,6,9,12。数字的含意和上面第一个例子一样。
【输出格式】
单独的一行包括一个用空格分开的将所有指针指向12:00的最短移动顺序的列表。
如果有多种方案,输出那种使其连接起来数字最小的方案。(举例来说5246<9311)。
【输入样例】
9 9 12 6 6 6 6 3 6
【输出样例】
4 5 8 9
【思路】
枚举,先预处理一下每种情况记录在a数组中,在分别从第一个开始往后枚举回溯,知道找到一个符合条件的情况。因为每种变换方法可以使用0~3次,并且每种变换方法在前与在后是等效的。所以,利用递归,按题中顺序枚举所有可能的解,并且每次记录下途径,那么第一种解就是我们要求的答案,输出即可。并且此方法简单易懂,复杂度很低。在usaco上测试最大的才用了0. 读入数据,把3,6,9,12变成1 2 3 4;
更多方法见http://www.nocow.cn/index.php/USACO/clocks
【代码】
- Executing...
- Test 1: TEST OK [0.000 secs, 276 KB]
- Test 2: TEST OK [0.000 secs, 276 KB]
- Test 3: TEST OK [0.022 secs, 276 KB]
- Test 4: TEST OK [0.000 secs, 276 KB]
- Test 5: TEST OK [0.011 secs, 276 KB]
- Test 6: TEST OK [0.011 secs, 276 KB]
- Test 7: TEST OK [0.011 secs, 276 KB]
- Test 8: TEST OK [0.022 secs, 276 KB]
- Test 9: TEST OK [0.043 secs, 276 KB]
- All tests OK.
{
ID : c_CaM.19
LANG: PASCAL
TASK: clocks
}
Program CaM(input,output);
Var
a:array[0..10,0..10] of longint;
x,i,j:longint;
ans:string;
q,b:array[0..100] of integer;
Procedure innt;
Begin
assign(input,'clocks.in'); reset(input);
assign(output,'clocks.out'); rewrite(output);
End;
Procedure outt;
Begin
close(input);
close(output);
End;
Procedure print;
Var
i,j:longint;
Begin
for i:=1 to 9 do
if q[i] mod 4<>0 then exit; //判断是否是12 12 12 12
ans:='';
for i:=1 to 9 do
for j:=1 to b[i] do
ans:=ans+chr(i+48)+' ';
delete(ans,length(ans),1);
writeln(ans); outt;
halt;
End;
Procedure Go_Deep(k:longint);
Var
i,j:longint;
Begin
if k=10 then print
else
Begin
for i:=0 to 3 do
Begin
b[k]:=i;
for j:=1 to a[k,0] do
inc(q[a[k,j]],i);
Go_Deep(k+1);
for j:=1 to a[k,0] do
dec(q[a[k,j]],i);
End;
End;
End;
Begin
innt;
a[1,0]:=4; a[1,1]:=1; a[1,2]:=2; a[1,3]:=4; a[1,4]:=5;
a[2,0]:=3; a[2,1]:=1; a[2,2]:=2; a[2,3]:=3;
a[3,0]:=4; a[3,1]:=2; a[3,2]:=3; a[3,3]:=5; a[3,4]:=6;
a[4,0]:=3; a[4,1]:=1; a[4,2]:=4; a[4,3]:=7;
a[5,0]:=5; a[5,1]:=2; a[5,2]:=4; a[5,3]:=5; a[5,4]:=6; a[5,5]:=8;
a[6,0]:=3; a[6,1]:=3; a[6,2]:=6; a[6,3]:=9;
a[7,0]:=4; a[7,1]:=4; a[7,2]:=5; a[7,3]:=7; a[7,4]:=8;
a[8,0]:=3; a[8,1]:=7; a[8,2]:=8; a[8,3]:=9;
a[9,0]:=4; a[9,1]:=5; a[9,2]:=6; a[9,3]:=8; a[9,4]:=9;
for i:=1 to 9 do
Begin
read(x);
q[i]:=x div 3; //处理3 6 9 12 -> 1 2 3 4
End;
Go_Deep(1);
End.
浙公网安备 33010602011771号