[蓝桥杯] 剪邮票

[蓝桥杯] 剪邮票

【题目描述 - Problem Description】

如【图1.jpg】, 有12张连在一起的12生肖的邮票。

现在你要从中剪下5张来,要求必须是连着的。

(仅仅连接一个角不算相连) 比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

【题解】

  这里全排列大法不是那么好用。
  然而毕竟范围小,完全可以不考虑效率DFS暴力枚举。

【最终结果】

116

【代码 C++】

 1 #include <cstdio>
 2 #include <cstring>
 3 int map[13][2], mtx[5][6], q[5], opt;
 4 void init(){
 5     int i, j, n;
 6     for (i = n = 1; i <= 3; ++i) for (j = 1; j <= 4; ++j, ++n){
 7         map[n][0] = i; map[n][1] = j;
 8     }
 9 }
10 int sum(int y, int x){
11     if (!mtx[y][x]) return 0;
12     mtx[y][x] = 0;
13     return 1 + sum(y + 1, x) + sum(y - 1, x) + sum(y, x + 1) + sum(y, x - 1);
14 }
15 void DFS(int last, int i){
16     if (i < 5){
17         while (++last <= 12){
18             q[i] = last;
19             DFS(last, i + 1);
20         }
21     }
22     else{
23         memset(mtx, 0, sizeof mtx);
24         for (i = 0; i < 5; ++i) mtx[map[q[i]][0]][map[q[i]][1]] = 1;
25         if (sum(map[q[0]][0], map[q[0]][1]) == 5) ++opt;
26     }
27 }
28 int main() {
29     init();
30     DFS(0, 0);
31     printf("%d", opt);
32     return 0;
33 }
原文地址:https://www.cnblogs.com/Simon-X/p/6516380.html