[藍橋杯] 剪郵票
【題目描述 - 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 }