枚举
【问题描述】
小红给定如下一个 6 × 6 矩阵:
11 8 3 27 24 1
2 21 16 35 17 4
9 29 20 30 5 10
36 33 13 6 23 7
31 14 15 28 12 25
34 19 18 37 22 39
小苯需要从中恰好选择 3 个两两不重叠的 1 × 2 或 2 × 1 子矩形并染红,要求每个
被染红区域内两个数的和都是奇数。
如果两个方案选出的 3 个区域每个都完全相同,则认为它们是同一种方案,选择顺
序不作区分。
#include <iostream>
#include <vector>
#include <cstdint>
using namespace std;
struct Domino {
uint8_t a, b;
Domino(uint8_t a_, uint8_t b_) : a(a_), b(b_) {}
};
bool overlap(const Domino& x, const Domino& y) {
return (x.a == y.a) || (x.a == y.b) || (x.b == y.a) || (x.b == y.b);
}
int main() {
int data[6][6] = {
{11, 8, 3, 27, 24, 1},
{2, 21, 16, 35, 17, 4},
{9, 29, 20, 30, 5, 10},
{36, 33, 13, 6, 23, 7},
{31, 14, 15, 28, 12, 25},
{34, 19, 18, 37, 22, 39}
};
vector<Domino> dominoes;
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 6; ++j) {
if (j + 1 < 6 && ((data[i][j] + data[i][j+1]) & 1)) {
uint8_t a = i * 6 + j;
uint8_t b = i * 6 + j + 1;
dominoes.emplace_back(a, b);
}
if (i + 1 < 6 && ((data[i][j] + data[i+1][j]) & 1)) {
uint8_t a = i * 6 + j;
uint8_t b = (i + 1) * 6 + j;
dominoes.emplace_back(a, b);
}
}
}
unsigned int n =dominoes.size();
int count = 0;
for(int i=0;i<n-2;i++){
for(int j=i+1;j<n-1;j++){
if (overlap(dominoes[i], dominoes[j])) continue;
for(int k=j+1;k<n;k++){
if (overlap(dominoes[i], dominoes[k]) || overlap(dominoes[j], dominoes[k]))
continue;
count++;
}
}
}cout<<count;
return 0;
}