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 }

 



你可能感兴趣的:(USACO)