LQ0146 七段码DFS+并查集
Posted 海岛Blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0146 七段码DFS+并查集相关的知识,希望对你有一定的参考价值。
题目来源:蓝桥杯2020初赛 A组D题
题目描述
小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有7 段可以发光的二极管,分别标记为a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
输出格式
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。
问题分析
7段数码管的每一段看作图的一个结点,相邻的段画一条边,构成一个图。
对于图,用DFS+并查集来解决,算出所有的组合。
其实,需要考虑亮1段的情形(7种);亮2段的情形,这时2段需要相邻;亮3段的情形,…;…;亮7段的情形(1种)。
更为通用的程序逻辑,考虑起来更难。
AC的C语言程序如下:
/* LQ0146 七段码 */
#include <stdio.h>
#include <string.h>
#define N 7
int g[N][N], s[N], ans = 0;
int f[N];
void UFInit()
for (int i = 0; i < N; i++) f[i] = i;
int Find(int a) return a == f[a] ? a : (f[a] = Find(f[a]));
void dfs(int u)
if (u == N)
UFInit();
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (g[i][j] && s[i] && s[j])
f[Find(i)] = Find(j);
int cnt = 0;
for (int i = 0; i < N; i++)
if (s[i] && f[i] == i)
cnt++;
if (cnt == 1) ans++;
else
s[u] = 1;
dfs(u + 1);
s[u] = 0;
dfs(u + 1);
int main()
memset(g, 0, sizeof g);
g[0][1] = g[0][5] = 1;
g[1][0] = g[1][2] = g[1][6] = 1;
g[2][1] = g[2][3] = g[2][6] = 1;
g[3][2] = g[3][4] = 1;
g[4][3] = g[4][5] = g[4][6] = 1;
g[5][0] = g[5][4] = g[5][6] = 1;
g[6][1] = g[6][2] = g[6][4] = g[6][5] = 1;
memset(s, 0, sizeof s);
dfs(0);
printf("%d\\n", ans);
return 0;
以上是关于LQ0146 七段码DFS+并查集的主要内容,如果未能解决你的问题,请参考以下文章