拨钟问题
来源:互联网 发布:重庆市网络知识竞赛 编辑:程序博客网 时间:2024/04/29 18:20
有9个时钟,排成一个3*3的矩阵。
|-------| |-------| |-------|| | | | | | ||---O | |---O | | O || | | | | ||-------| |-------| |-------| A B C |-------| |-------| |-------|| | | | | || O | | O | | O || | | | | | | | ||-------| |-------| |-------| D E F |-------| |-------| |-------|| | | | | || O | | O---| | O || | | | | | | ||-------| |-------| |-------| G H I (图 1)
现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
移动 影响的时钟 1 ABDE 2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI
3 3 0 2 2 2 2 1 2
4 5 8 9
思路描述:
一个移动,如果做四次相当于没有做,所以每种移动最多做3次。先确定123步做的次数,枚举出所有种情况,则只有第4步能影响A,第5步能影响B,第6步能影响C,第7步能影响D,第9步能影响F,则根据ABCDF的情况可以分别确定45679步的次数,再通过G的情况确定8步次数,检查是否每一个钟都为12点,成功则与之前的成功情况比较,如果步数更少则取代之前情况。完成所有情况后,排序输出。
代码如下:
#include <iostream>#include <string.h>using namespace std;int OriRotateTime[9];int RotateTime[9];int change[9][9]={{-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 step=0;//步数计数int minstep=36;//最小步数计数int minmovestep[27];//步数输出数组int movestep[27];//步数数组void refresh(int s)//更新时钟状态{for(int i=0;i<9;i++){if(RotateTime[i]+change[s][i]>=0)RotateTime[i]=RotateTime[i]+change[s][i];elseRotateTime[i]=RotateTime[i]+change[s][i]+4;}}void Result()//结果处理,排序输出{int mid;for(int i=0;i<minstep;i++){for(int j=i+1;j<minstep;j++){if(minmovestep[i]>minmovestep[j]){mid=minmovestep[i];minmovestep[i]=minmovestep[j];minmovestep[j]=mid;}}}for(int i=0;i<minstep;i++){cout<<minmovestep[i]<<" ";}}void Select(){for(int m=0;m<4;m++)//确定4567步的次数{int t=RotateTime[m];while(t>0){movestep[step++]=m+4;refresh(m+3);t--;}}int t=0;t=RotateTime[5];while(t>0)//确定9{movestep[step++]=9;refresh(8);t--;}t=RotateTime[6];while(t>0)//确定8{movestep[step++]=8;refresh(7);t--;}if(RotateTime[4]==0&&RotateTime[7]==0&&RotateTime[8]==0)//检查是否成功{if(step<minstep)//与之前最小值比较{minstep=step;memcpy(minmovestep,movestep,sizeof(movestep));}}memcpy(RotateTime,OriRotateTime,sizeof(RotateTime));//恢复初值开始下一种情况for(int i=0;i<27;i++){movestep[i]=0;}step=0;}int main(){for(int i=0;i<9;i++){char a;cin>>a;switch(a){case '0':OriRotateTime[i]=0;break;case '1':OriRotateTime[i]=3;break;case '2':OriRotateTime[i]=2;break;case '3':OriRotateTime[i]=1;break;}}memcpy(RotateTime,OriRotateTime,sizeof(RotateTime));for(int i=0;i<4;i++){for(int j=0;j<4;j++){for(int k=0;k<4;k++)//确定123步的次数{for(int s=i;s>0;s--)//更新1步的操作{movestep[step++]=1;refresh(0);}for(int s=j;s>0;s--)//更新2步的操作{movestep[step++]=2;refresh(1);}for(int s=k;s>0;s--)//更新3步的操作{movestep[step++]=3;refresh(2);}Select();}}}Result();return 0;}
阅读全文
0 0
- 拨钟问题pku1166
- 拨钟问题
- 拨钟问题
- Openjudge2814:拨钟问题
- 枚举-拨钟问题
- openjudge-拨钟问题
- 拨钟问题
- 拨钟问题
- 拨钟问题
- 枚举-拨钟问题
- poj 1166 拨钟问题
- POJ-1816 拨钟问题
- 拨钟问题(蛮力法)
- openjudge 2814:拨钟问题
- 拨钟问题 穷举法
- 【贪心枚举】拨钟问题
- 拨钟问题的若干解法
- poj(1166)——拨钟问题
- bzoj3101 N皇后
- [leetcode]解决Clone Graph的一点小心得
- 特手天气
- [设计模式]观察者模式
- Python 每日记录
- 拨钟问题
- C#事件与委托(水壶烧水事件)
- 大端与小端
- C语言_我的初成长
- 上传笔记【一】webUploader 多文件上传并保存数据库
- bzoj 2823(计算几何+最小覆盖圆)
- 记录采用cloudera-manager安装CDH集群的过程
- bzoj3048 [Usaco2013 Jan]Cow Lineup
- 听到别人发论文的感想