[蓝桥杯2016初赛]剪邮票
[蓝桥杯2016初赛]剪邮票
时间限制: 1 Sec 内存限制: 256 MB
提交: 296 解决: 128
[状态] [提交] [命题人:外部导入]
题目描述
如下图, 有12张连在一起的12生肖的邮票。现在你要从中剪下5张来,要求必须是连着的。(仅仅连接一个角不算相连)
比如,下面两张图中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
输出
请填写表示方案数目的整数。
#include
#include
#include
#include
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;
}