2814拨钟问题
解题思路,和上一题画家问题一样,本题也使用枚举的思想来解决,注意到这里对于时钟的操作,如果达到四次,
那么那就和没有操作是一样的,故这里可以使用4进制来模拟每个操作的状态,最坏情况下的执行次数,4的9次方。
下面是题目和代码:
2814:拨钟问题
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
有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 - 输入
- 9个整数,表示各时钟指针的起始位置,相邻两个整数之间用单个空格隔开。其中,0=12点、1=3点、2=6点、3=9点。
- 输出
- 输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号从小到大输出结果。相邻两个整数之间用单个空格隔开。
- 样例输入
-
3 3 0 2 2 2 2 1 2
- 样例输出
-
4 5 8 9
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100#include <map>
#include <string>
#include <iostream>
#include <algorithm>
using
namespace
std;
map<
int
, string> mapStudent;
bool
IsAllThree(
int
s[9]){
for
(
int
i=0;i<9;i++){
if
(s[i]!=3)
return
false
;
}
return
true
;
}
int
main()
{
int
action[9][9]={0};
action[0][0]=action[0][1]=action[0][3]=action[0][4]=1;
action[1][0]=action[1][1]=action[1][2]=1;
action[2][1]=action[2][2]=action[2][4]=action[2][5]=1;
action[3][0]=action[3][3]=action[3][6]=1;
action[4][1]=action[4][3]=action[4][4]=action[4][5]=action[4][7]=1;
action[5][2]=action[5][5]=action[5][8]=1;
action[6][3]=action[6][4]=action[6][6]=action[6][7]=1;
action[7][6]=action[7][7]=action[7][8]=1;
action[8][4]=action[8][5]=action[8][7]=action[8][8]=1;
int
s[9]={0};
int
clock
[9]={0};
int
best[9]={0};
int
min=32767;
for
(
int
i=0;i<9;i++){
cin>>
clock
[i];
}
while
(1){
int
temp_min=0;
for
(
int
ii=0;ii<9;ii++){
temp_min+=s[ii];
}
int
turnFlag=0;
if
(temp_min>min) turnFlag=1;
if
(turnFlag==0){
for
(
int
ii=0;ii<9;ii++){
for
(
int
jj=0;jj<9;jj++){
clock
[jj]+=(action[ii][jj]*s[ii]);
}
}
int
flag=1;
//1 success 0 fail
for
(
int
ii=0;ii<9;ii++){
if
((
clock
[ii]%4)!=0){
flag=0;
break
;
}
}
/*cout<<"clock:"<<endl;
for(int ii=0;ii<9;ii++){
cout<<clock[ii]<<" ";
}
cout<<endl;*/
//cout<<"flag:"<<flag<<endl;
//cout<<"temp_min:"<<temp_min<<endl;
if
(flag){
//cout<<"here"<<endl;
if
(min>temp_min){
//cout<<"best:"<<endl;
for
(
int
iii=0;iii<9;iii++){
best[iii]=s[iii];
//cout<<best[iii]<<" ";
}
//cout<<endl;
min=temp_min;
//cout<<"in"<<endl;
}
}
for
(
int
ii=0;ii<9;ii++){
for
(
int
jj=0;jj<9;jj++){
clock
[jj]-=(action[ii][jj]*s[ii]);
}
}
}
if
(IsAllThree(s))
break
;
s[0]+=1;
int
i=0;
while
(s[i]>=4){
s[i]=0;
s[i+1]+=1;
i++;
}
}
if
(min!=0){
for
(
int
i=0;i<9;i++){
if
(best[i]!=0){
for
(
int
j=0;j<best[i];j++)
cout<<i+1<<
" "
;
}
}
cout<<endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
2016-04-07 C#中部分方法返回值类型为什么只能是void?