拔钟问题
来源:互联网 发布:各国谷歌域名 编辑:程序博客网 时间:2024/05/16 01:58
编程题#2:拨钟问题
来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
有9个时钟,排成一个3*3的矩阵。
现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
输入
从标准输入设备读入9个整数,表示各时钟指针的起始位置。0=12点、1=3点、2=6点、3=9点。
输出
输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号大小,输出结果。
样例输入
样例输出
问题分析:枚举前三个钟的不同组合,再以前三个钟的状态来决定后面钟的状态,最后判断是否成立;
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
//执行某一操作后更新时针状态
void operate(intoperations[10][10], intclock2[10], int opNum, int opCount)
{
for (int i = 1; i <= 9; i++)
{
clock2[i] += operations[opNum][i] * opCount;
clock2[i] %= 4;
}
}
int main(void)
{
//保存原始时钟状态
int clock[10];
//保存移动后的时钟状态
int clock2[10];
//保存最小的移动次数
int minTimes = 28;
//保存移动方法的操作次数
int opTimes[10];
//保存最小的操作次数移动方法
int minOpTimes[10];
//九种操作对应的数组
int operations[10][10] =
{
{ 0 },
//
{ 0, 1, 1, 0, 1, 1, 0, 0, 0,0 }, // ABDE
{ 0, 1, 1, 1, 0, 0, 0, 0, 0,0 }, // ABC
{ 0, 0, 1, 1, 0, 1, 1, 0, 0,0 }, // BCEF
{ 0, 1, 0, 0, 1, 0, 0, 1, 0,0 }, // ADG
{ 0, 0, 1, 0, 1, 1, 1, 0, 1,0 }, //BDEFH
{ 0, 0, 0, 1, 0, 0, 1, 0, 0,1 }, //CFI
{ 0, 0, 0, 0, 1, 1, 0, 1, 1,0 }, // DEGH
{ 0, 0, 0, 0, 0, 0, 0, 1, 1,1 }, // GHI
{ 0, 0, 0, 0, 0, 1, 1, 0, 1,1 }, // EFHI
};
//保存1,2,3的操作的所有组合
int move123[64][3];
for (int i = 0; i < 64; i++)
{
int num = i;
for (int j = 2; j >= 0; j--)
{
move123[i][j] = num % 4;
num = num / 4;
} //每种时钟最多被执行三次,所以取1到3的所有组合4^3;
}
//输入数据;
for (int x = 1; x <= 9; x++)
cin >> clock[x];
for (int i = 0; i < 64; i++)
{
//将原始数据copy toclock2;
memcpy(clock2, clock, sizeof(int) * 10);
//清空保存的操作次数
memset(opTimes, 0, sizeof(int) * 10);
//尝试前三个的不同组合
for (int j = 1; j <= 3; j++)
{
opTimes[j] = move123[i][3- j];
operate(operations,clock2, j, opTimes[j]);
}
//4,5,6,由前三的状态决定
for (int j = 4; j <= 6; j++)
{
opTimes[j] = (4 -clock2[j - 3]) % 4;
operate(operations,clock2, j, opTimes[j]);
}
//7由D决定
opTimes[7] = (4 - clock2[4])% 4;
operate(operations, clock2,7, opTimes[7]);
//9由F决定
opTimes[9] = (4 - clock2[6])% 4;
operate(operations, clock2,9, opTimes[9]);
//判断E是否为零,还有最后三是否相等
if (clock2[5] == 0 && clock2[7]== clock2[8] && clock2[8] == clock2[9])
{
opTimes[8] = (4 -clock2[7]) % 4;
int tem = 0;
for (int i = 1; i <= 9; i++)
tem += opTimes[i];
if (tem < minTimes) //更新次数,取最少的
{
minTimes = tem;
memcpy(minOpTimes,opTimes, sizeof(int) * 10);
}
}
}
vector <int> result;
for (int i = 1; i <= 9; i++)
{
while (minOpTimes[i]--) //将操作号及次数作压入操作
{
result.push_back(i);
}
}
sort(result.begin(),result.end());//排序
vector<int>::iterator it;
for (it = result.begin(); it !=result.end(); it++)//输出数据
cout << *it << ' ';
cout << endl;
return 0;
}
- 拔钟问题
- 解决BT5的VPN拔号问题
- 巧妙解决拔通VPN后不能上网问题
- 关于Android耳机插拔的问题(ACTION_HEADSET_PLUG )
- 拔筋------拔颈
- 拔叉
- 拔罐
- 拔萝卜
- 拔智齿
- android插拔耳麦广播android.intent.action.HEADSET_PLUG中间出的问题
- android 4.0.3 usb插拔提示音播放问题分析
- 解决BT5的VPN拔号和Wicd Network Manager错误问题
- android 4.0.3 usb插拔提示音播放问题分析
- android 写文件到SD卡以后,立即拔卡的问题
- 电脑问题解决_171007_1_win10笔记本插拔耳机后扬声器无声的问题
- 如何解决Windows8.1(32bit&64bit)下Cisco VPN Client拔号时报442错误的问题
- Mac系统中移动硬盘热拔(强制退出)后,在插上不显示移动硬盘的问题和解决办法
- 面试一些点拔
- 冒泡 选择 插入排序 二分查找 代码备忘
- leetcode系列(四):罗马数Roman to Integer
- 控制寄存器
- 【Hadoop】hadoop2.6.4 源码编译
- CSS 选择器(下)20160815-0015
- 拔钟问题
- 双向链表
- Java学习提要——异常的基本概念
- openstack源码阅读笔记1 开发环境搭建
- 文章标题
- MySQL中JDBC的使用
- Spring的BeanFactoryPostProcessor和BeanPostProcessor
- 控制寄存器和系统地址寄存器
- mybatis 中的<![CDATA[ ]]>