题目:
分析:简化问题 0 -6表示 这a-f 7段,最短可以表示 2**7-1 ==127个情况,完全可以穷举每一种表示然后数
设计的位运算
x >> i & 1:判断数字 x 的二进制排列中,第 i 位是否为 1;
000 0000 从右到左分别表示a-f 循环1-127,哪位为1打印出对应字符" |"
以下c++代码参考他人
#include <iostream>
using namespace std;
int main()
{
int cnt = 1;
for (int x = 1; x <= 127; x ++)
{
cout << "====" << cnt ++ << "====" << endl;
for (int i = 0; i < 7; i ++)
{
if(i == 0)
{
if(x >> i & 1) cout << " --";
cout << endl;
}
if(i == 1)
{
if(x >> i & 1) cout << '|';
else cout << " ";
}
if(i == 2)
{
if(x >> i & 1) cout << " |";
cout << endl;
}
if(i == 3)
{
if(x >> i & 1) cout << " --";
cout << endl;
}
if(i == 4)
{
if(x >> i & 1) cout << '|';
else cout << " ";
}
if(i == 5)
{
if(x >> i & 1) cout << " |";
cout << endl;
}
if(i == 6)
{
if(x >> i & 1) cout << " --";
cout << endl;
}
}
cout << endl;
}
return 0;
}
这样数容易漏,找方案的总数,明显dfs,只只有7段每段可选可不选,如果选完7端就利用并查集判断联通子块的个数,如果为1就记录
注意题目要求:
要求所有发光的二极管是连成一片的。
因此我们需要维护相邻关系=》构建边集ed
用 1 ~ 7 来代表 a ~ g;
若某两个二极管相邻,那么就在它们之间连一条边;(在构建并查集集合时,只有相邻的、并且都是发光状态才合并)
先用 dfs 枚举出二极管的所有亮灭情况;
再用 并查集 判断是否只有一个连通块;(统计所有集合,只有一个元素并且 是开状态 )
N=10
e=[[0]*N for i in range(N)]
st=[0]*N
p=[0]*N
ans=0
def find(x):
if p[x]!=x:
p[x]=find(p[x])
return p[x]
def dfs(u):
global p,ed,st,ans
if u==8:
for i in range(1,8):
p[i]=i
for i in range(1,8):
for j in range(1,8):
if e[i][j]==1 and st[i]==1 and st[j]==1:
p[find(i)]= find(j)
cnt = 0#cnt不能定义为全局,每次都必须清空,记录联通块数量的
for i in range(1,8):
if st[i]==1 and p[i]==i:
cnt +=1
if cnt==1 : ans+=1
return
st[u]=1#当前u二极管有两种状态,往下搜的时候分两种情况
dfs(u+1)
st[u]=0
dfs(u+1)
e[1][2] = e[1][6] = 1
e[2][1] = e[2][7] = e[2][3] = 1
e[3][2] = e[3][7] = e[3][4] = 1
e[4][3] = e[4][5] = 1
e[5][4] = e[5][7] = e[5][6] = 1
e[6][1] = e[6][7] = e[6][5] = 1
e[7][2] = e[7][3] = e[7][5] = e[7][6] = 1
dfs(1)
print(ans)#80