本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二 极管,分别标记为 a,b,c,d,e,f,g。小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符 的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如 c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上 一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a,b,c,d,e 发光,f,g 不发光可以用来表达一种字符。
例如:b,f 发光,其他二极管不发光则不能用来表达一种字符,因为发光 的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
#include
using namespace std;
// a b c d e f g
// 1 2 3 4 5 6 7
// 1 - 2 6
// 2 - 1 7 3
// 3 - 4 7 2
// 4 - 3 5
// 5 - 4 7 6
// 6 - 1 7 5
// 7 - 2 3 5 6
// 用邻接矩阵表示两个端点之间的灯管是不是连着
int g[7][7] = {
{0, 1, 0, 0, 0, 1, 0},
{1, 0, 1, 0, 0, 0, 1},
{0, 1, 0, 1, 0, 0, 1},
{0, 0, 1, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 1, 1},
{1, 0, 0, 0, 1, 0, 1},
{0, 1, 1, 0, 1, 1, 0}
};
int used[7]={0}; // 表示每个二极管是否有用过
int ans=0; // 表示最后结果
int p[7]; // 存储这个点的 parent
int find(int x) // 查询该节点的根节点
{
if(p[x]==x) // 如果该点的根节点是自己
{
return p[x]; // 返回自己的编号
}
else
{
p[x]=find(p[x]); //父节点设为根节点
return p[x]; //返回父节点
// 如果它不是根节点 ,一层一层访问父节点,直至根节点(根节点的标志就是父节点是本身)
// 要判断两个元素是否属于同一个集合,只需要看它们的根节点是否相同即可
// 本代码已经实现路径优化
}
}
void merge(int i,int j) // 把 i 和 j 合并到一个根节点下
{
if(p[find(i)]!=p[find(j)])
{
p[find(i)]=p[j]; // i 找出来的的根节点设为 j 的根节点
}
}
void dfs(int a) // a 表示已经遍历了 a 个二极管
{
if(a==7)
{
// 用并查集的思路去判断选择的这些发光二极管是不是连成一片(在同一个集合中)
// 如果确实连成一片,就计数 1 次
for(int i=0;i<7;i++)
{
p[i]=i; // 初始化,根节点是它自己
}
for(int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
//cout<<"----test-----"<
if(g[i][j]==1&&used[i]==1&&used[j]==1)
{
//cout<
merge(i,j); // 如果 i 和 j 连着,同时 i 亮,j 也亮,把它们的根节点设为一个
}
}
}
int root_num=0; // 所有亮着的节点的根节点数
for(int i=0;i<7;i++)
{
// 判断亮的这些是不是在一个集合
// 比如 左边两根亮,右边两根也亮,但是它们不连着,也就是有两个根节点,不符合题目要求
// 排除这种情况
if(p[i]==i&&used[i])
{
root_num++; // 遍历所有亮着的二极管,如果它的根节点是自己,根结点数+1
}
}
if(root_num==1) //如果只有一个根节点
{
ans++;
}
return;
}
used[a]=1; // 把这个二极管点亮,看这种情况下的树
dfs(a+1);
used[a]=0; // 把这个二极管熄灭,看这种情况下的树
dfs(a+1);
}
int main()
{
dfs(0); // 从 0 开始(0-6)
cout<<ans;
return 0;
}
这个题对于我来说还是有点超前了……很多地方都不懂,改来改去现在才对。
merge
函数,里面要判断两个节点的根节点是否为同一个点。这个文章是用暴力求解的:2020年蓝桥杯七段码,虽然很暴力,但是如果实在想不到算法这个很好理解,也很好实现,需要注意它后面列了三种特殊情况,这个有点难想。
这两个文章全用的是并查集+dfs来解决:第十一届蓝桥杯 ——七段码 、 七段码(2020年蓝桥杯省赛)。
同时发现了宝藏博主的文章,对历年题很有研究,而且题解很简洁易懂:蓝桥杯省赛 C/C++ ABC组题解(第四届 ~ 第十二届)