[USACO 6.5.4]The Clocks
题目大意
给出3*3共9个时钟的初始状态和结束状态(即指针全指向12)以及一系列的操作方法,求操作序列.详情请看题面.
题解
1.操作顺序是没有关系的.
2.每个操作只能执行0~3次.
代码
/* TASK:clocks LANG:C++ */ #include <cstdio> #include <cstring> using namespace std; const char mtd[9][7] = {"ABDE\0", "ABC\0", "BCEF\0", "ADG\0", "BDEFH\0", "CFI\0", "DEGH\0", "GHI\0", "EFHI\0"}; const int a[4] = {1, 10, 100, 1000}; const int b[4] = {0, 1, 11, 111}; int clock[9], rot[9], cnt[9], path[30], np, now; void dfs(int dep, int dnow) { if (dep == 9) { bool flag = true; for (int i = 0; i < 9; ++i) if (clock[i] != rot[i] % 4) { flag = false; break; } if (flag && dnow < now) { np = 0; for (int i = 0; i < 9; ++i) for (int j = 0; j < cnt[i]; ++j) path[np++] = i + 1; now = dnow; } return; } for (int i = 0; i < 4; ++i) { cnt[dep] = i; for (int lv = 0; lv < strlen(mtd[dep]); ++lv) rot[mtd[dep][lv] - 'A'] += i; dfs(dep + 1, dnow * a[i] + (dep+1) * b[i]); for (int lv = 0; lv < strlen(mtd[dep]); ++lv) rot[mtd[dep][lv] - 'A'] -= i; } } int main() { freopen("clocks.in", "r", stdin); freopen("clocks.out", "w", stdout); for (int i = 0; i < 9; ++i) { scanf("%d", &clock[i]); clock[i] = (4 - clock[i]/3) % 4; } memset(rot, 0, sizeof(rot)); now = 0x7fffffff; dfs(0, 0); for (int i = 0; i < np-1; ++i) printf("%d ", path[i]); printf("%d\n", path[np-1]); return 0; }