USACO1.4.2--The Clocks

The Clocks
IOI'94 - Day 2

Consider nine clocks arranged in a 3x3 array thusly:

|-------|    |-------|    |-------|    
|       |    |       |    |   |   |    
|---O   |    |---O   |    |   O   |          
|       |    |       |    |       |           
|-------|    |-------|    |-------|    
    A            B            C

|-------|    |-------|    |-------|
|       |    |       |    |       |
|   O   |    |   O   |    |   O   |
|   |   |    |   |   |    |   |   |
|-------|    |-------|    |-------|
    D            E            F

|-------|    |-------|    |-------|
|       |    |       |    |       |
|   O   |    |   O---|    |   O   |
|   |   |    |       |    |   |   |
|-------|    |-------|    |-------|
    G            H            I

The goal is to find a minimal sequence of moves to return all the dials to 12 o'clock. Nine different ways to turn the dials on the clocks are supplied via a table below; each way is called a move. Select for each move a number 1 through 9 which will cause the dials of the affected clocks (see next table) to be turned 90 degrees clockwise.

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

Example

Each number represents a time accoring to following table:

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 

[But this might or might not be the `correct' answer; see below.]

PROGRAM NAME: clocks

INPUT FORMAT

Lines 1-3: Three lines of three space-separated numbers; each number represents the start time of one clock, 3, 6, 9, or 12. The ordering of the numbers corresponds to the first example above.

SAMPLE INPUT (file clocks.in)

9 9 12
6 6 6
6 3 6

OUTPUT FORMAT

A single line that contains a space separated list of the shortest sequence of moves (designated by numbers) which returns all the clocks to 12:00. If there is more than one solution, print the one which gives the lowest number when the moves are concatenated (e.g., 5 2 4 6 < 9 3 1 1).

SAMPLE OUTPUT (file clocks.out)

4 5 8 9
解题思路:DFS。每种方案最多选三次,因为旋转四次就恢复原状态了,相当于没进行操作。由于方案的顺序并不重要,因此满足要求就可以输出,中断搜索。
表示被一个BUG坑死了,整整坑了两天。仅仅因为把赋值符号“=”打成“==”了,然后就一直不输出结果,惨痛的教训啊,以后一定要记住!!!
View Code
 1 /*
 2 ID:spcjv51
 3 PROG:clocks
 4 LANG:C
 5 */
 6 #include<stdio.h>
 7 #include<stdlib.h>
 8 #define MAXSTEPS 30
 9 const int a[9][9]=
10 {
11     {1,1,0,1,1,0,0,0,0},
12     {1,1,1,0,0,0,0,0,0},
13     {0,1,1,0,1,1,0,0,0},
14     {1,0,0,1,0,0,1,0,0},
15     {0,1,0,1,1,1,0,1,0},
16     {0,0,1,0,0,1,0,0,1},
17     {0,0,0,1,1,0,1,1,0},
18     {0,0,0,0,0,0,1,1,1},
19     {0,0,0,0,1,1,0,1,1},
20 };
21 int now[9],minstep;
22 int path[MAXSTEPS],time[9];
23 int init()
24 {
25     int i,k;
26     for(i=0; i<9; i++)
27     {
28         scanf("%d",&k);;
29         now[i]=(k/3)%4;
30     }
31     memset(path,0,sizeof(path));
32     memset(time,0,sizeof(time));
33 }
34 int ok()
35 {
36     int i;
37     for(i=0; i<9; i++)
38         if(now[i]%4!=0)return 0;
39     return 1;
40 }
41 void output()
42 {
43     int i;
44     for(i=0;i<minstep-1;i++)
45     printf("%d ",path[i]+1);
46     printf("%d\n",path[minstep-1]+1);
47 
48 }
49 
50 
51 void change(int i)
52 {
53     int j;
54     for(j=0; j<9; j++)
55         now[j]+=a[i][j];
56 }
57 void regain(int i)
58 {
59     int j;
60     for(j=0; j<9; j++)
61         now[j]-=a[i][j];
62 
63 }
64 void search(int step)
65 {
66     int i,j;
67     if(step>=MAXSTEPS) return;
68     if(ok())
69     {
70         minstep=step;
71         output();
72         return;
73     }
74     if (step==0) j=0;
75     else if(time[path[step-1]]<3) j=path[step-1];
76     else
77         j=path[step-1]+1;
78     for(i=j; i<9; i++)
79     {
80         change(i);
81         time[i]++;
82         path[step]=i;
83         search(step+1);
84         regain(i);
85         time[i]--;
86 
87     }
88 }
89 
90 int main(void)
91 {
92     freopen("clocks.in","r",stdin);
93     freopen("clocks.out","w",stdout);
94     init();
95     search(0);
96     return 0;
97 }

USACO上的题解真是太犀利了,好简短。

You can precalculate a matrix a as following:

a[i][0],a[i][1],....,a[i][8] is the number of moves '1','2','3',...'9' necessarly to move ONLY clock i (where 0 < i <= 8 - there are 9 clocks: 0=A, 1=B, ... 8=I) 90 degrees clockwise. So, you have the matrix:

int a[9][9]= { {3,3,3,3,3,2,3,2,0},
               {2,3,2,3,2,3,1,0,1},
               {3,3,3,2,3,3,0,2,3},
               {2,3,1,3,2,0,2,3,1},
               {2,3,2,3,1,3,2,3,2},
               {1,3,2,0,2,3,1,3,2},
               {3,2,0,3,3,2,3,3,3},
               {1,0,1,3,2,3,2,3,2},
               {0,2,3,2,3,3,3,3,3} };

That means: to move ONLY the clock 0 (clock A) 90 degrees clockwise you have to do {3,3,3,3,3,2,3,2,0}, 3 moves of type 1, three moves of type 2, ..., 2 moves of type 8, 0 moves of type 9, etc.

To move ONLY the clock 8 (clock I), you have to do the moves {0,2,3,2,3,3,3,3,3}: 0 moves of type 1, 2 moves of type 2... 3 moves of type 9....

That's it! You count in a vector v[9] how many moves of each type you have to do, and the results will be modulo 4 (%4 - 5 moves of any type have the same effect 1 move has). The source code:

View Code
 1 #include <stdio.h>
 2 
 3 int a[9][9]= { {3,3,3,3,3,2,3,2,0},
 4                {2,3,2,3,2,3,1,0,1},
 5                {3,3,3,2,3,3,0,2,3},
 6                {2,3,1,3,2,0,2,3,1},
 7                {2,3,2,3,1,3,2,3,2},
 8                {1,3,2,0,2,3,1,3,2},
 9                {3,2,0,3,3,2,3,3,3},
10                {1,0,1,3,2,3,2,3,2},
11                {0,2,3,2,3,3,3,3,3} };
12 int v[9];
13 
14 int main() {
15     int i,j,k;
16     freopen("clocks.in","r",stdin);
17     for (i=0; i<9; i++) {
18         scanf("%d",&k);
19         for(j=0; j<9; j++)
20              v[j]=(v[j]+(4-k/3)*a[i][j])%4;
21     }
22     fclose(stdin);
23 
24     k=0;
25     freopen("clocks.out","w",stdout);
26     for (i=0; i<9; i++)
27         for (j=0; j<v[i]; j++)
28             if (!k) { printf("%d",i+1); k=1; }
29             else    printf(" %d",i+1);
30     printf("\n");
31     fclose(stdout);
32     return 0;
33 }

 



posted on 2013-01-21 11:59  仗剑奔走天涯  阅读(596)  评论(0编辑  收藏  举报

导航