枚举-拨钟问题(算法基础 第2周)

枚举-拨钟问题

问题描述:
这里写图片描述
这里写图片描述
分析:
原题是POJ上的:http://cxsjsxmooc.openjudge.cn/test/Z/
这道题跟‘画家问题’和‘熄灯问题’是一类题目,注意减小搜索空间:
这里写图片描述
参考:http://www.cnblogs.com/CCBB/archive/2011/09/13/2175043.html

源码:

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

int initial_clocks[10]={0}, adjusted_clocks[10]={0}, op[10]={0};
vector<int> perfect_adjust;
const int operations[10][10] =
{
    {0},
    //  A  B  C  D  E  F  G  H  I
    {0, 1, 1, 0, 1, 1, 0, 0, 0, 0},  //op1: ABDE
    {0, 1, 1, 1, 0, 0, 0, 0, 0, 0},  //op2: ABC
    {0, 0, 1, 1, 0, 1, 1, 0, 0, 0},  //op3: BCEF
    {0, 1, 0, 0, 1, 0, 0, 1, 0, 0},  //op4: ADG
    {0, 0, 1, 0, 1, 1, 1, 0, 1, 0},  //op5: BDEFH
    {0, 0, 0, 1, 0, 0, 1, 0, 0, 1},  //op6: CFI
    {0, 0, 0, 0, 1, 1, 0, 1, 1, 0},  //op7: DEGH
    {0, 0, 0, 0, 0, 0, 0, 1, 1, 1},  //op8: GHI
    {0, 0, 0, 0, 0, 1, 1, 0, 1, 1}  //op9: EFHI
};
/*
调整时钟:
参数:
op_num:调整方式(9种)
op_counts:操作次数
*/
void operate(int op_num, int op_counts) {
    for(int k=1; k<=9; k++) {
        adjusted_clocks[k] += operations[op_num][k]*op_counts;
        adjusted_clocks[k] %= 4;
    }
}

int guess() {
    op[4]=(4-adjusted_clocks[1])%4;
    operate(4, op[4]);
    op[5]=(4-adjusted_clocks[2])%4;
    operate(5, op[5]);
    op[6]=(4-adjusted_clocks[3])%4;
    operate(6, op[6]);
    op[7]=(4-adjusted_clocks[4])%4;
    operate(7, op[7]);
    op[8]=(4-adjusted_clocks[7])%4;
    operate(8, op[8]);
    if (adjusted_clocks[5]==adjusted_clocks[6] && adjusted_clocks[5]==adjusted_clocks[8] && adjusted_clocks[5]==adjusted_clocks[9]){
        op[9] = (4-adjusted_clocks[9])%4;
        operate(9, op[9]);
        int steps=0;
        for (int k=1; k<=9; k++) {
            steps += op[k];
        }
        return steps;
    }
    return 101;
}

int enumerate() {
    int c=0;
    int minsteps=101;
    int steps=0;
    while(c<64) {
        op[3]=c/16;
        op[2]=c%16/4;
        op[1]=c%4;  
        memcpy(adjusted_clocks, initial_clocks, sizeof(initial_clocks));
        operate(3, op[3]);
        operate(2, op[2]);
        operate(1, op[1]);
        steps = guess();
        if (steps<minsteps) {
            minsteps = steps;
            perfect_adjust.clear();
            for(int k=1; k<=9; k++){
                while(op[k]--) {
                    perfect_adjust.push_back(k);
                }
            }
        }
        c++;
    }
    return minsteps;
}

int main() {

    for (int k=1; k<10; k++){
        cin >> initial_clocks[k];
    }
    if (enumerate()<101){
        for (int k=0; k<perfect_adjust.size(); k++){
            cout << perfect_adjust.at(k) << ' ';
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值