枚举-拨钟问题(算法基础 第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;
}
阅读更多

更多精彩内容