对每一段都有两种情况,选和不选,二进制枚举每一种情况(或则dfs),然后判断选择的段会组成几个连通块,当连通块的数量为1时答案+1
code:
#include<iostream>
#include<cstring>
using namespace std;
const int N = 100;
int head[N],e[N],ne[N];
int cnt;
int ans;
bool st[10];
int fa[10];
void add(int u,int v){
e[cnt] = v, ne[cnt] = head[u] , head[u] = cnt ++;
}
int get(int x){
if(x == fa[x]) return x;
return fa[x] = get(fa[x]);
}
void dfs(int x){
if(x == 7){//如果选择完了,看看有几个连通块
for(int i = 0 ;i < 7; i ++ ) fa[i]=i;
for(int i = 0 ;i < 7 ;i ++){
if(st[i] == 0) continue;
for(int j = head[i] ; j != -1 ;j = ne[j]){
int v = e[j];
if(st[v] == 0) continue;
int fx = get(i), fy = get(v);
if(fx != fy) fa[fx] = fy;
}
}
int index = 0;
for(int i = 0;i < 7 ;i ++ ){
if(fa[i] == i && st[i]) index++; //index为连通块的个数
}
if(index == 1) ans++;
return ;// 7个数码管都已经被选择过了则返回即可
}
st[x]=1;
dfs(x+1);
st[x]=0;
dfs(x+1);
}
int main()
{
memset(head, -1 , sizeof(head));
add(0,1),add(0,5);
add(1,0),add(1,6),add(1,2);
add(2,1),add(2,6),add(2,3);
add(3,4),add(3,2);
add(4,3),add(4,6),add(4,5);
add(5,0),add(5,6),add(5,4);
add(6,1),add(6,2),add(6,4),add(6,5);
//dfs 爆搜,每个数码管有2种状态
dfs(0);//从第0个开始进行选择,这个和二进制枚举是差不多的
cout << ans <<endl;
return 0;
}