【笔记】《算法竞赛入门》习题7-3 UVa211_多米诺效应

题目: 使用28个多米诺骨牌拼凑出输入的二维数组

思路,使用一个二维数组标记每个多米诺骨牌的牌号,下标为Pips,一个典型的回溯

//
// Created by hsby on 2021/1/30.
//

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

int Dir[2][2] = {{0, 1}, {1, 0}};

int dom[7][7] = {0};
int g[7][8];
int ans[7][8];
int t;

bool judge(){
    for (int i = 0; i < 7; ++i) {
        for (int j = 0; j < 8; ++j) {
            if (!ans[i][j]) return false;
        }
    }
    return true;
}

void dfs(int ai){
    // 如果判断可行,输出结果
    if (judge()){
        for (int i = 0; i < 7; ++i) {
            for (int j = 0; j < 8; ++j) {
                printf("%2d ", ans[i][j]);
            }
            cout << endl;
        }
        cout << endl;
        t++;
        return;
    }
    // flag表示在ai行之后找到了可以继续遍历的起点
    int flag = 1;
    // 从ai行开始找
    for (int i = ai; i < 7 && flag; ++i) {
        for (int j = 0; j < 8 && flag; ++j) {
            if (ans[i][j]) continue;
            // 找到了,开始往右和下两个方向探索
            for (int k = 0; k < 2; ++k) {
                int ti = i + Dir[k][0];
                int tj = j + Dir[k][1];
                if (ans[ti][tj] || ti > 6 || ti < 0 || tj > 7 || tj < 0) continue;
                flag = 0;
                int a = min(g[i][j], g[ti][tj]);
                int b = max(g[i][j], g[ti][tj]);
                int d = dom[a][b];
                ans[i][j] = d;
                ans[ti][tj] = d;
                dfs(i);
                ans[i][j] = 0;
                ans[ti][tj] = 0;
            }
        }
    }
}

int main(){
    int cnt = 1;
    for (int i = 0; i < 7; ++i) {
        for (int j = i; j < 7; ++j) {
            dom[i][j] = cnt++;
        }
    }

    int n = 1;
    while (!cin.eof()){
        memset(g, 0, sizeof(g));
        memset(ans, 0, sizeof(ans));
        t = 0;
        cout << "Layout #" << n << ":" << endl << endl;
        for (int i = 0; i < 7; ++i) {
            for (int j = 0; j < 8; ++j) {
                cin >> g[i][j];
                cout << g[i][j] << " ";
            }
            cout << endl;
        }
        cout << endl;
        cout << "Maps resulting from layout #" << n << " are:" << endl << endl;
        dfs(0);
        cout << "There are " << t++ <<  " solution(s) for layout #" << n++ << "." << endl << endl;
    }

    return 0;
}
posted @ 2021-01-30 19:20  汉森伯逸  阅读(86)  评论(0编辑  收藏  举报