[蓝桥杯] 剪邮票
[蓝桥杯] 剪邮票
【题目描述 - 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 }