拨钟问题

这道题真是费了我好大力气(估计我还会回来看不少次qwq)
题解(DFS):
每个钟有4种情况,暴力枚举49种情况,这里只要一维数组就可以记录钟的状态(nowClock[] 和 oriClock[])
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int oriClock[9]; // 时钟初始状态 5 int nowClock[9]; // 时钟当前状态 6 7 string moves[9] = 8 {"ABDE", "ABC", "BCEF", "ADG", "BDEFH", "CFI", "DEGH", "GHI", "EFHI"}; 9 10 int moveTimes[9] = {0}; // 每一个时钟的操作次数 11 int minTimes = 0xfffffff; // 最小操作次数 12 int result[9]; // 结果 13 14 void dfs(int n) 15 { 16 if (n == 9) 17 { 18 memcpy(nowClock, oriClock, sizeof(nowClock)); // 把初始状态复制给nowClock 19 int times = 0; // 统计移动次数 20 // 把9种move的移动序列用于时钟之上,然后统计移动次数 21 for (int i = 0; i < 9; ++i) 22 { 23 if (moveTimes[i]) 24 { 25 // 读取移动的指令,修改时钟状态 26 for (int k = 0; k < moves[i].size(); ++k) 27 { 28 nowClock[moves[i][k] - 'A'] = 29 (nowClock[moves[i][k] - 'A'] + moveTimes[i]) % 4; 30 times += moveTimes[i]; 31 } 32 } 33 } 34 // 判断9个时钟是否都复原, 也就是nowClock[i]全部为0 35 bool flag = 1; 36 for (int i = 0; i < 9; ++i) 37 { 38 if (nowClock[i] != 0) 39 { 40 flag = 0; 41 break; 42 } 43 } 44 // 找到一组解 45 if (flag && minTimes > times) 46 { 47 minTimes = min(minTimes, times); 48 memcpy(result, moveTimes, sizeof(result)); 49 } 50 return; 51 } 52 53 for (int i = 0; i < 4; ++i) 54 { 55 moveTimes[n] = i; 56 57 // 进入下一个钟 58 dfs(n + 1); 59 } 60 return; 61 } 62 63 int main() 64 { 65 // 读入时钟状态 66 for (int i = 0; i < 9; ++i) 67 cin >> oriClock[i]; 68 // 递归搜索 69 dfs(0); 70 // 输出结果 71 for (int i = 0; i < 9; ++i) 72 for (int j = 0; j < result[i]; ++j) 73 cout << i + 1 << " "; 74 /* 75 result 0 1 2 3 4 5 6 7 8 76 0 0 0 1 1 0 0 1 1 77 若某一步骤出现重复则输出多次 78 */ 79 return 0; 80 }

浙公网安备 33010602011771号