[蓝桥杯2016初赛]剪邮票

[蓝桥杯2016初赛]剪邮票

时间限制: 1 Sec 内存限制: 256 MB
提交: 296 解决: 128
[状态] [提交] [命题人:外部导入]
题目描述
如下图, 有12张连在一起的12生肖的邮票。现在你要从中剪下5张来,要求必须是连着的。(仅仅连接一个角不算相连)

在这里插入图片描述
比如,下面两张图中,粉红色所示部分就是合格的剪取。
在这里插入图片描述
在这里插入图片描述

请你计算,一共有多少种不同的剪取方法。
输出
请填写表示方案数目的整数。

#include <algorithm>
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;

int a[12] = { 0,0,0,0,0,0,0,1,1,1,1,1 };

void dfs(vector<vector<int>>& m, int i, int j) {
    m[i][j] = 0;
    //四个方向
    if (i - 1 >= 0 && m[i - 1][j] == 1)dfs(m, i - 1, j);
    if (i + 1 <= 2 && m[i + 1][j] == 1)dfs(m, i + 1, j);
    if (j - 1 >= 0 && m[i][j - 1] == 1)dfs(m, i, j - 1);
    if (j + 1 <= 3 && m[i][j + 1] == 1)dfs(m, i, j + 1);
}

bool check(int arr[]) {
    //生成a对应的二维矩阵
    vector<vector<int>> map(3, vector<int>(4));
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            map[i][j] = arr[i * 4 + j] == 1 ? 1 : 0;
        }
    }
    //连通性检测,如果连通块的数量为1,则是一种正确的方案
    int count = 0;//连通块的数量
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            if (map[i][j] == 1) {
                dfs(map, i, j);
                count++;
            }
        }
    }
    return count == 1;
}

int main()
{
    int ans = 0;
    //用a数组产生全排列代表选择5个位置的邮票
    do {
        if (check(a)) {
            ans++;
        }
    } while (next_permutation(a, a + 12));//全排列函数 
    cout << ans << endl;
    //cout << clock() << "ms" << endl;//看看跑了多长时间 
    return 0;
}
发布了25 篇原创文章 · 获赞 17 · 访问量 704

猜你喜欢

转载自blog.csdn.net/mu_mu_mu_mu_mu/article/details/105617151
今日推荐