如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
思路
这一题用简单的dfs在表中选五个是不行的,因为 T 字型的是dfs不出来的,就比如图3.
所以要通过next_permutation来全排列,任选五个格子,通过dfs求出连通量是否为1,如果为1则满足条件,cont+1
答案:116
代码
#include <iostream>
#include <algorithm>
using namespace std;
int cont = 0;
int map[3][4];
int a[12] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
int xx[4] = {1, -1, 0, 0};
int yy[4] = {0, 0, 1, -1};
void dfs(int a, int b)
{
map[a][b] = 2;
for (int i = 0; i < 4; i++) {
int zx = a + xx[i];
int zy = b + yy[i];
if (zx < 0 || zx > 2 || zy < 0 || zy > 3 || map[zx][zy] != 1) continue;
dfs(zx, zy);
}
}
bool judge()
{
for (int i = 0; i < 12 ; i++) map[i / 4][i % 4] = a[i];
int cnt = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
if (map[i][j] == 1) {
dfs(i, j);
cnt++;
}
}
}
if (cnt == 1) return true;
else return false;
}
int main()
{
do {
if (judge()) cont++;
} while (next_permutation(a, a + 12));
cout << cont << endl;
return 0;
}