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+并查集的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯 七段码 python (2020)

七段码(2020省赛填空)

第十一届蓝桥杯 ——七段码

Python 用推导式解决“七段码”问题

数字图像处理 使用opencv+python识别七段数码显示器的数字

2/21 并查集+dfs