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 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#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;
    }

  

posted @   张杨  阅读(1018)  评论(0编辑  收藏  举报
编辑推荐:
· 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?
点击右上角即可分享
微信分享提示