程序设计与算法二郭炜枚举002拨钟问题及解题思路

题目

有9个时钟,排成一个3*3的矩阵。
在这里插入图片描述
现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
移动 影响的时钟

1 ABDE
2 ABC
3 BCEF
4 ADG
5 BDEFH
6 CFI
7 DEGH
8 GHI
9 EFHI

输入

9个整数,表示各时钟指针的起始位置,相邻两个整数之间用单个空格隔开。其中,0=12点、1=3点、2=6点、3=9点。

输出

输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号从小到大输出结果。相邻两个整数之间用单个空格隔开。

样例输入

3 3 0
2 2 2
2 1 2

样例输出

4 5 8 9

解题方法

根据我在网上查到的方法,大意是时钟共有4种状态,而不管时钟出于何种状态,拨动时钟4次后时钟会回到最开始的状态,相当于没有移动。这里的1~9种移动方法,任意一种方法使用4次之后,其影响的时钟都会回到最开始的状态,相当于没有使用这种移动方法。于是,每种移动方法只有使用0次、1次、2次和3次这四种情况,一共也就是4^9种情况,枚举这些情况即可。
优化的方法是,像熄灯问题一样,先枚举例如1至3移动方法使用次数的各种情况,一种方法4种情况一共也就是4^3种情况。再根据ABC三个钟只能分别由剩余的456方法移动,以此决定4至6方法的使用次数。再由D、E钟只能由79方法移动,以此决定79方法的移动次数。而GHI钟只能由8方法同时决定移动次数,所以在经过以上的移动后,必须状态相同。最后,检查F钟是否为12点即可。
以下为枚举所有情况的代码。

代码实现

# include <iostream>
# include <cstring>
# include <string>
# include <memory>
using namespace std;
//判断移动方法是否正确
int ClockMove(int clock[][3], int m1, int m2, int m3, int m4, int m5, int m6, int m7, int m8, int m9)
{
	if((clock[0][0]+m1+m2+m4)%4==0){
		if((clock[0][1]+m1+m2+m3+m5)%4==0){
			if((clock[0][2]+m2+m3+m6)%4==0){
				if((clock[1][0]+m1+m4+m5+m7)%4==0){
					if((clock[1][1]+m1+m3+m5+m7+m9)%4==0){
						if((clock[1][2]+m3+m5+m6+m9)%4==0){
							if((clock[2][0]+m4+m7+m8)%4==0){
								if((clock[2][1]+m5+m7+m8+m9)%4==0){
									if((clock[2][2]+m6+m8+m9)%4==0){
										return 1;
									}
									else return 0;
								}
								else return 0;
							}
							else return 0;
						}
						else return 0;
					}
					else return 0;
				}
				else return 0;
			}
			else return 0;
		}
		else return 0;
	}
	else return 0;
}
//输出
int Output(int a[], int x, int &min)
{
	for(int i = a[x];i>0;i--,min--){
		if(min) cout<<x<<" ";
		else cout<<x;
	}
}

int main()
{
	int clock[3][3] = {0};
	int a[10] = {0}; //记录最终方法
	int b[10] = {0}; //记录中间方法
	int min = -1;
    //输入
	for(int i = 0;i<3;i++)
	for(int j = 0;j<3;j++) cin>>clock[i][j];
	
	for(int i1 = 0;i1<4;i1++){
		b[1] = i1;
	    for(int i2 = 0;i2<4;i2++){
	    	b[2] = i2;
	    	for(int i3 = 0;i3<4;i3++){
	    		b[3] = i3;
	    		for(int i4 = 0;i4<4;i4++){
	    			b[4] = i4;
	    			for(int i5 = 0;i5<4;i5++){
	    				b[5] = i5;
	    				for(int i6 = 0;i6<4;i6++){
	    					b[6] = i6;
	    					for(int i7 = 0;i7<4;i7++){
	    						b[7] = i7;
	    						for(int i8 = 0;i8<4;i8++){
	    							b[8] = i8;
	    							for(int i9 = 0;i9<4;i9++){
	    								b[9] = i9;
	    								int cnt = i1+i2+i3+i4+i5+i6+i7+i8+i9;
		                                if(cnt<min||min==-1) {
			                                if(ClockMove(clock,i1,i2,i3,i4,i5,i6,i7,i8,i9)){
				                                if(min>cnt||min==-1){
					                                min = cnt;
					                                for(int j = 1;j<10;j++) a[j] = b[j];
				                                }
			                                }
		                                }
									}
								}
							}
						}
					}
			    }
		    }
	    }
	}

	for(int i = 1;i<10;i++) Output(a,i,min);
	
	return 0;
}	
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于FPGA:电子钟的设计报告全文共10页,当前为第1页。基于FPGA:电子钟的设计报告全文共10页,当前为第1页。 基于FPGA:电子钟的设计报告全文共10页,当前为第1页。 基于FPGA:电子钟的设计报告全文共10页,当前为第1页。 电子钟的设计报告 姓 名:< > 基于FPGA:电子钟的设计报告全文共10页,当前为第2页。基于FPGA:电子钟的设计报告全文共10页,当前为第2页。 组 别:< > 基于FPGA:电子钟的设计报告全文共10页,当前为第2页。 基于FPGA:电子钟的设计报告全文共10页,当前为第2页。 专业班级:< > 目 录 目 录 1 一、数字钟的设计要求 2 、顶层设计 2 三、模块 3 1.顶层模块 3 2.分频器模块 4 3.按键消抖模块 4 4.计时模块 5 5.显示模块 6 6.报时和闹钟模块 6 四、 系统调试及运行结果分析 7 1、硬件调试 7 2、软件调试 8 3、调试过程及结果 8 (1)显示模块调试 8 (2)时间系统模块调试 9 五、总结 9 基于FPGA:电子钟的设计报告全文共10页,当前为第3页。基于FPGA:电子钟的设计报告全文共10页,当前为第3页。一、数字钟的设计要求 基于FPGA:电子钟的设计报告全文共10页,当前为第3页。 基于FPGA:电子钟的设计报告全文共10页,当前为第3页。 设计一个具有时、分、秒计时第电子钟电路,按24小时制记时。 要求: 1、准确计时,以数字形式显示时、分、秒的时间; 2、具有分、时校正功能,校正输入脉冲频率为1Hz; 3、具有仿广播电台整点报时的功能,即每逢59分51秒、53秒、55秒及57秒时,发出4声500Hz低音,在59分59秒时发出一声1kHz高音,它们的持续时间均为1秒。最后一声高音结束的时刻恰好为正点时刻。 4、具有定时闹钟功能,且最长闹铃时间为一分钟。要求可以任意设置闹钟的时、分;闹铃信号为500Hz和1kHz的方波信号,两种频率的信号交替输出,且均持续1S。设置一个停止闹铃控制键,可以停止输出闹铃信号。 、顶层设计 采用自顶向下的设计方法,首先根据数字时钟的功能要求进行顶层设计和分析,用FPGA实现系统的计时、显示驱动、按键输入处理、仿广播电台整点报时的功能。根据实训平台的硬件资源情况,输入信号包括时钟输入和按键输入,其中系统时钟由实训平台核心板50MHz 晶振提供,拨码开关作为校时、闹钟时间设置和复位的信号输入,输出信号包括峰鸣器控制输出、8位动态数码管位选和段选控制输出。 数字电字时钟系统主要有分频器模块、按键消抖模块、计时模块、整点报时和闹铃模块和显示驱动模块构成。 基于FPGA:电子钟的设计报告全文共10页,当前为第4页。基于FPGA:电子钟的设计报告全文共10页,当前为第4页。三、模块 基于FPGA:电子钟的设计报告全文共10页,当前为第4页。 基于FPGA:电子钟的设计报告全文共10页,当前为第4页。 1.顶层模块 如下图所示。 基于FPGA:电子钟的设计报告全文共10页,当前为第5页。基于FPGA:电子钟的设计报告全文共10页,当前为第5页。2.分频器模块 基于FPGA:电子钟的设计报告全文共10页,当前为第5页。 基于FPGA:电子钟的设计报告全文共10页,当前为第5页。 分频器模块的主要功能是为其他模块提供时钟信号。 输入端口:50MHz的时钟信号; 输出端口:1Hz、500Hz和1kHz三种频率的时钟信号。 如下图所示。 3.按键消抖模块 作为机械开关的键盘,在按键操作时,机械触点的弹性及电压突跳等原因,在触点闭合或开启的瞬间会出现电压抖动,如下图所示。实际应用中如果不进行处理将会造成误触发。 按键去抖动关键在于提取稳定的低电平状态,滤除前沿、后沿抖动毛刷。对于一个按键信号,可以用一个脉冲对它进行采样。如果连续三采样为低电平,可基于FPGA:电子钟的设计报告全文共10页,当前为第6页。基于FPGA:电子钟的设计报告全文共10页,当前为第6页。以认为信号已经处于键稳定状态,这时输出一个低电平按键信号。继续采样的过程中如果不能满足连续三次采样为低,则认为键稳定状态结束,这时输出变为高电平。 基于FPGA:电子钟的设计报告全文共10页,当前为第6页。 基于FPGA:电子钟的设计报告全文共10页,当前为第6页。 按键消抖模块功能是消除校时按键的机械抖动。 输入端口:消抖时钟,按键K1,K2和K3; 输出端口:校时信号set_h,校分信号set_m,显示模式mode。 如下图所示。 4.计时模块 计时模块是数字钟的主体电路,包括正常计时、对时间进行校正、设置闹钟时间和判断闹铃等功能。 输出端口:clk_1Hz_in,秒计时脉冲输入; mode,校时和闹钟设置功能切换信号输入; set_h,set_m,校时和

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值