http://ace.delos.com/usacoprob2?a=aTRAhrlUGW0&S=clocks
有9个时钟,每个时钟的表针只能指向上、下、左、右四个位置。有9种操作方式,每种操作方式可以使某几种时钟顺时针旋转90度。要求使用最小的操作次数,让这所有9个时钟都指向上面。
USACO给出的分析:
Notice that the order in which we apply moves is irrelevant, and that applying a move four times is the same as applying it not at all.
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:
#include <stdio.h> 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} }; int v[9]; int main() { int i,j,k; freopen("clocks.in","r",stdin); for (i=0; i<9; i++) { scanf("%d",&k); for(j=0; j<9; j++) v[j]=(v[j]+(4-k/3)*a[i][j])%4; } fclose(stdin); k=0; freopen("clocks.out","w",stdout); for (i=0; i<9; i++) for (j=0; j<v[i]; j++) if (!k) { printf("%d",i+1); k=1; } else printf(" %d",i+1); printf("\n"); fclose(stdout); return 0; }