拨钟问题

传送门:http://bailian.openjudge.cn/practice/2814?lang=en_US

拨钟问题,画家问题,熄灯问题,这三个题有共同的特点:

1.每个开关或者移动的步数是有次数限制的。拨钟问题移动次数最多为4,因为移动4次跟不移m动一样,画家问题和熄灯问题次数为2,因为开关按两次跟没按一样。

2.移动顺序或者按开关的顺序不重要。都是为了达到目标状态,先按哪个开关和后按哪个开关不影响最终结果。

3.每次按开关或者移动或影响周围环境。

下面谈谈拨钟问题:

一共有9种移动,每种移动会影响多个钟,最后要求所有钟拨到12点的位置。

每个钟有一个开始状态0到3,其中,0=12点、1=3点、2=6点、3=9点。最后要求到达12点的位置也就是目标状态是每个钟=0。

研究一下9种移动:

移动    影响的时钟

 1         ABDE 2         ABC 3         BCEF 4         ADG 5         BDEFH 6         CFI 7         DEGH 8         GHI 9         EFHI   这样看可能看不出来啥,把它转换一下:

时钟 会被哪些移动影响

 A         124 B         1235 C         236 D         1457 E         13579 F         3569 G         478 H         5789 I         689这样就很清楚了,用int a[10]记录每个时钟的初始状态,int move[10]记录9种移动的次数,可以枚举9种移动的次数(最多为4),目标是每个钟经过一系列移动后达到12点,即(a[i]+move[1~9])%4==0,一定要余4,因为表针经过移动后可能会超过一圈。要使移动序列最短,也就是要使移动次数总和最小,需要设置一个全局变量和全局数组记录最小次数和相应的移动序列。
 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     int a[11];
 7     int change[11];
 8     int best[11];
 9     int minCount = 999999;
10      for(int i = 1;i<=9;++i)
11      {
12          cin >>a[i];
13      }
14      memset(change,0,sizeof(change));//把change数组里的元素全部初始化为0
15      int sum = 0;
16      //每种移动最多就能进行4次
17
18          for(change[1] = 0;change[1]<4;change[1]++)
19          for(change[2] = 0;change[2]<4;change[2]++)
20          for(change[3] = 0;change[3]<4;change[3]++)
21          for(change[4] = 0;change[4]<4;change[4]++)
22          for(change[5] = 0;change[5]<4;change[5]++)
23          for(change[6] = 0;change[6]<4;change[6]++)
24          for(change[7] = 0;change[7]<4;change[7]++)
25          for(change[8] = 0;change[8]<4;change[8]++)
26          for(change[9] = 0;change[9]<4;change[9]++)
27          {
28              sum = 0;
29              sum+= (a[1]+change[1]+change[2]+change[4])%4;//A
30              sum+= (a[2]+change[1]+change[2]+change[3]+change[5])%4;//B
31              sum+= (a[3]+change[2]+change[3]+change[6])%4;//C
32              sum+= (a[4]+change[1]+change[4]+change[5]+change[7])%4;//D
33              sum+= (a[5]+change[1]+change[3]+change[5]+change[7]+change[9])%4;//E
34              sum+= (a[6]+change[3]+change[5]+change[6]+change[9])%4;//F
35              sum+= (a[7]+change[4]+change[7]+change[8])%4;//G
36              sum+= (a[8]+change[5]+change[7]+change[8]+change[9])%4;//H
37              sum+= (a[9]+change[6]+change[8]+change[9])%4;//I
38              if(sum == 0)//要求最短移动序列
39              {
40                  int count = 0;
41                  for(int j=1;j<=9;j++)
42                  {
43                       count += change[j];
44                 }
45                   if(count < minCount)
46                   {
47                       minCount = count;
48                     memcpy(best,change,sizeof(change));
49                 }
50                 for(int j=1;j<=9;j++)
51                  {
52                       while(best[j]--)
53                       {
54                           cout << j<<" ";
55                       }
56                 }
57              }
58          }
59     return 0;
60  } 

原文地址:https://www.cnblogs.com/knmxx/p/10464594.html

时间: 2024-10-29 11:48:40

拨钟问题的相关文章

002:拨钟问题

总时间限制:  1000ms 内存限制:  65536kB 描述 有9个时钟,排成一个3*3的矩阵. |-------| |-------| |-------|| | | | | | ||---O | |---O | | O || | | | | ||-------| |-------| |-------| A B C |-------| |-------| |-------|| | | | | || O | | O | | O || | | | | | | | ||-------| |----

枚举--拨钟问题

参考http://blog.sina.com.cn/s/blog_b1e4dca501013z88.html思路,给出非9重循环的程序实现: #include <iostream>#include <stdio.h> using namespace std; // clock的位置int A[9]; // 思路 :首先确定“局部” :前三个操作.// 然后查看后续操作能否满足要求. bool isClock(int* a){ for (int i=0;i<9;i++) { i

ACM/ICPC 之 枚举(POJ1681-画家问题+POJ1166-拨钟问题)

POJ1681-画家问题 枚举的经典例题,枚举第一行即可,其余行唯一. 1 //画家问题,y表示黄色,w表示白色,怎样让墙上所有方格为y,操作类似熄灯问题poj1222 2 //memory 136K Time: 297 Ms 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 9 #define INF

7.18练习 DFS+递归

A 百练2811 熄灯问题 总时间限制: 1000ms 内存限制: 65536kB 描述 有一个由按钮组成的矩阵,其中每行有6个按钮,共5行.每个按钮的位置上有一盏灯.当按下一个按钮后,该按钮以及周围位置(上边.下边.左边.右边)的灯都会改变一次.即,如果灯原来是点亮的,就会被熄灭:如果灯原来是熄灭的,则会被点亮.在矩阵角上的按钮改变3盏灯的状态:在矩阵边上的按钮改变4盏灯的状态:其他的按钮改变5盏灯的状态. 在上图中,左边矩阵中用X标记的按钮表示被按下,右边的矩阵表示灯状态的改变.对矩阵中的每

【算法】搞定[机试]算法刷题 全文超过80页pdf

目录 算法专题 一.树和图 1. 二叉树构造和遍历 2. 朋友圈 - 并查集 3. 公共朋友 - 非朋友圈 4. 哈夫曼树 5. 其他二叉树性质相关计算 6. 图的连通分量 7. 最小生成树 8. 单源最短路径 - dijkstra 二.枚举搜索 1. 按钮开关问题 2. 多层枚举问题 三.递归搜索 1. 简单递归 2. 递增排列组合类 3. 全排列问题 4. 草丛问题 5. 迷宫问题 6. 广度优先搜索的剪枝 7. 总操作步数固定枚举问题 四.数学问题 1. 高精度计算 2. 素数和质因子分解

L1-018. 大笨钟

时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 微博上有个自称"大笨钟V"的家伙,每天敲钟催促码农们爱惜身体早点睡觉.不过由于笨钟自己作息也不是很规律,所以敲钟并不定时.一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么"当"数就等于那个整点数:如果过了整点,就敲下一个整点数.另外,虽然一天有24小时,钟却是只在后半天敲1~12下.例如在23:00敲钟,就是"当当当当当当当

六年征程新跨越,正益移动敲响上市宝钟

1月13日,正益移动迎来新年的开门大吉,董事长王国春及众高管.投资人,一起敲响新三板上市宝钟(股票代码:835032),开启资本市场新征途.正益移动一直专注于移动技术与移动创新服务的探索和实践,在"互联网+双创"的大背景下,实现跨越式发展. "咚~ ~ ~"正益移动董事长王国春及投资人敲响上市宝钟,开启新征程. 忆往昔,六载创业路,专注移动,披荆斩棘,砥砺前行: 2010年,正益,为移动而生,在北京中关村创立: 2012年,AppCan 品牌正式推出,以"

Openwrt15.05网关后pptp外拨失败的解决办法

路由器升级openwrt chaos_calmer 15.05版后发现NAT后面的客户端外拨pptp vpn服务器失败,经google后得知,在14.07版本中默认安装的又一个叫做 kmod-ipt-nathelper-extra 的软件包,该软件包实现了pptp客户端穿透openwrt网关的功能,而到了15.05版后,该软件包不在默认安装,且该软件包已改名为  kmod-nf-nathelper-extra,重新安装回来就行了: opkg install kmod-nf-nathelper-e

钟无艳

钟无艳 其实我怕你总夸奖高估我坚忍 其实更怕你只懂得欣赏我品行 无人及我用字绝重拾了你信心 无人问我可甘心演这伟大化身 其实我想间中崩溃脆弱如恋人 垂在你两臂中低得不需要身份 无奈被你识穿这个念头 得到好处的你 明示不想失去绝世好友 没有得你的允许我都会爱下去 互相祝福心软之际或者准我吻下去 我痛恨成熟到不要你望着我流泪 但漂亮笑下去仿佛冬天饮雪水 被你一贯的赞许却不配爱下去 在你悲伤一刻必须解慰找到我乐趣 我甘于当副车也是快乐着唏嘘 彼此这么了解难怪注定似兄妹一对 其实我怕你的好感基于我修养