Vijos1016.北京2008的挂钟
2015-08-04 17:37
1096 查看
试题请参见: https://vijos.org/p/1016
在2008北京奥运会雄伟的主会场的墙上, 挂着如上图所示的3*3的九个挂钟(一开始指针即时针指向的位置请根据输入数据调整). 然而此次奥运会给与了大家一个机会, 去用最少的移动操作改变上面的挂钟的时间全部为12点正(我们只考虑时针). 然而每一次操作并不是任意的, 我们必须按照下面给出的列表对于挂钟进行改变. 每一次操作我们给而且必须给指定的操作挂钟进行, 每一个挂钟顺时针转动90度. 列表如下:
有一个简单的”剪枝”, 每一个操作的最大次数为3次(即[0, 4)). 因为当时钟被调整到4次之后又会回到原点, 这显然不是最优解.
循环变量没有初始化
输出的时候写错了循环变量等
题目概述
在2008北京奥运会雄伟的主会场的墙上, 挂着如上图所示的3*3的九个挂钟(一开始指针即时针指向的位置请根据输入数据调整). 然而此次奥运会给与了大家一个机会, 去用最少的移动操作改变上面的挂钟的时间全部为12点正(我们只考虑时针). 然而每一次操作并不是任意的, 我们必须按照下面给出的列表对于挂钟进行改变. 每一次操作我们给而且必须给指定的操作挂钟进行, 每一个挂钟顺时针转动90度. 列表如下:
操作 | 指定的操作挂钟 |
---|---|
1 | ABDE |
2 | ABC |
3 | BCEF |
4 | ADG |
5 | BDEFH |
6 | CFI |
7 | DEGH |
8 | GHI |
9 | EFHI |
解题思路
这题解法有很多, 但是我们注意到就算穷举运算量也并不大. 于是我们就使用穷举.有一个简单的”剪枝”, 每一个操作的最大次数为3次(即[0, 4)). 因为当时钟被调整到4次之后又会回到原点, 这显然不是最优解.
遇到的问题
一些非常低级的小问题:循环变量没有初始化
输出的时候写错了循环变量等
源代码
#include <iostream> const size_t NUMBER_OF_CLOCKS = 9; const size_t NUMBER_OF_OPERATIONS = 9; /** * 最大操作次数. * 由于操作4次会回到原点, 没有必要继续搜索. */ const size_t MAX_NUMBER_OF_OPERATIONS = 4; /** * 获取当前对各个时钟操作的次数. * @return 对各个时钟操作的次数 */ int getOperationTimes(int* operations) { int operationTimes = 0; for ( size_t i = 0; i < NUMBER_OF_CLOCKS; ++ i ) { operationTimes += operations[i]; } return operationTimes; } /** * 获取最优的调整方案 * @param clocks - 当前每个时钟的时间([0, 4)的整数) * @param bestOperations - 对各个时钟最佳操作的次数 * @return 每个操作进行次数的数组 */ void getBestSolution(int* clocks, int* bestOperations) { /** * 存储时钟的初始状态. * 用于回溯, 在搜索失败后的rollback. */ int mirrorClocks[NUMBER_OF_CLOCKS] = {0}; /** * 存储对时钟的操作. */ int operations[NUMBER_OF_OPERATIONS][NUMBER_OF_CLOCKS] = { { 1, 1, 0, 1, 1, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 1, 1, 0, 0, 0 }, { 1, 0, 0, 1, 0, 0, 1, 0, 0 }, { 0, 1, 0, 1, 1, 1, 0, 1, 0 }, { 0, 0, 1, 0, 0, 1, 0, 0, 1 }, { 0, 0, 0, 1, 1, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0, 0, 1, 1, 1 }, { 0, 0, 0, 0, 1, 1, 0, 1, 1 } }; /** * 存储当前对各时钟操作的计数. * 记录对每个时钟操作的次数. */ int currentOperations[NUMBER_OF_CLOCKS] = {0}; for ( size_t i = 0; i < NUMBER_OF_CLOCKS; ++ i ) { mirrorClocks[i] = clocks[i]; } for ( currentOperations[0] = 0 ; currentOperations[0] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[0] ) { for ( currentOperations[1] = 0 ; currentOperations[1] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[1] ) { for ( currentOperations[2] = 0 ; currentOperations[2] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[2] ) { for ( currentOperations[3] = 0 ; currentOperations[3] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[3] ) { for ( currentOperations[4] = 0 ; currentOperations[4] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[4] ) { for ( currentOperations[5] = 0 ; currentOperations[5] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[5] ) { for ( currentOperations[6] = 0 ; currentOperations[6] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[6] ) { for ( currentOperations[7] = 0 ; currentOperations[7] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[7] ) { for ( currentOperations[8] = 0 ; currentOperations[8] < MAX_NUMBER_OF_OPERATIONS; ++ currentOperations[8] ) { // Rollback for ( size_t i = 0; i < NUMBER_OF_CLOCKS; ++ i ) { clocks[i] = mirrorClocks[i]; } bool isSuccessful = true; for ( size_t i = 0; i < NUMBER_OF_CLOCKS; ++ i ) { for ( size_t j = 0; j < NUMBER_OF_OPERATIONS; ++ j ) { clocks[i] += currentOperations[j] * operations[j][i]; } clocks[i] %= 4; if ( clocks[i] != 0 ) { isSuccessful = false; break; } } if ( !isSuccessful ) { continue; } // Save the solution int currentOperationTimes = getOperationTimes(currentOperations); int bestOperationTimes = getOperationTimes(bestOperations); if ( currentOperationTimes < bestOperationTimes ) { for ( size_t i = 0; i < NUMBER_OF_OPERATIONS; ++ i ) { bestOperations[i] = currentOperations[i]; } } } } } } } } } } } } int main() { /** * 存储时钟当前的状态. * 在搜索时不断改变. */ int clocks[NUMBER_OF_CLOCKS] = {0}; /** * 存储当前对各时钟操作计数的最优解. */ int bestOperations[NUMBER_OF_OPERATIONS] = { 10, 10, 10, 10, 10, 10, 10, 10, 10 }; for ( size_t i = 0; i < NUMBER_OF_CLOCKS; ++ i ) { std::cin >> clocks[i]; } getBestSolution(clocks, bestOperations); for ( size_t i = 0; i < NUMBER_OF_OPERATIONS; ++ i ) { for ( int j = 0; j < bestOperations[i]; ++ j ) { std::cout << ( i + 1 ) << " "; } } std::cout << std::endl; return 0; }
相关文章推荐
- Coursera台大机器学习技法课程笔记12-Neural Network
- perl实现守护进程
- leetcode 242
- ionic项目之ngcordova插件之camera
- JFinal项目是怎么诞生的?
- GUI编程:打开文件对话框、保存文件对话框、颜色选择对话框的使用
- Android异步消息处理机制(1)Handler基本使用
- HTML中出现双引号嵌套,里面的双引号换成单引号来用
- c++ 常用特定 c++11
- Control
- Highcharts的一些属性
- dig域名
- PopUpView滑动消失
- Actionbar是使用
- oracle 查询行号 导致一个整形不可空字段查出来全为0
- Unreal Engine 4 各平台的大小端问题
- promise链式
- 设置MySQL允许外网访问 费元星 feiyuanxing.com 站长
- 制作日历的方法总结
- Windows的DDE原理