[藍橋杯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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章