如
, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,,
中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
首先把标号改成 0…11
然后建图 得到邻接表g数组
接着DFS 注意只要连着就好 而不是得一条线下来
由于2^12次方很小,所以用二进制状态压缩判重
答案 116
#include <bits/stdc++.h>
using namespace std;
vector<int> g[12];
void add(int x, int y)
{
g[x].push_back(y);
g[y].push_back(x);
}
bool b[12];
int a[5];
int ans = 0;
bool bs[1<<13];
void dfs(int k, int u)
{
a[k] = u;
if (k == 4) {
int s = 0;
for (int i = 0; i < 5; i++) s += (1<<a[i]);
if (!bs[s]) bs[s] = true, ans++;
return;
}
for (int i = 0; i <= k; i++)
for (int v : g[a[i]]) {
if (b[v]) continue;
b[v] = true;
dfs(k + 1, v);
b[v] = false;
}
}
int main()
{
for (int i = 0; i < 12; i++) {
if (i < 8) {
if (i % 4 < 3) {
add(i, i + 1);
add(i, i + 4);
} else {
add(i, i + 4);
}
} else {
if (i < 11) add(i, i + 1);
}
}
memset(bs, 0, sizeof(bs));
for (int i = 0; i < 12; i++) {
memset(b, 0, sizeof(b));
b[i] = true;
dfs(0, i);
}
cout << ans << endl;
}