ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【蓝桥杯】七段码

2022-01-31 15:02:02  阅读:181  来源: 互联网

标签:map 结点 int cnt 蓝桥 发光 七段


七段码

小蓝要用七段码数码管来表示一种特殊的文字。

图片描述
在这里插入图片描述

上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二 极管,分别标记为 a, b, c, d, e, f, g。

小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符 的表达时,要求所有发光的二极管是连成一片的。

例如:b 发光,其他二极管不发光可以用来表达一种字符。

例如 c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上 一行的方案可以用来表示不同的字符,尽管看上去比较相似。

例如:a, b, c, d, e发光,f, g 不发光可以用来表达一种字符。

例如:b, f发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。

请问,小蓝可以用七段码数码管表达多少种不同的字符?

思路

  • 将七段码的七个段看成是图的七个结点,分别编号为a = 0,b = 1,c = 2,d = 3,e = 4,f = 5,g = 6

  • 则七段码可以转化为以下无向图:
    在这里插入图片描述

  • 转化为图之后,问题似乎变得明朗起来了,接下来就是这样的一个问题:
    给出k个结点(1<=k<=7),求在图中这k个结点连通的情况

  • 那么就有这么一个问题:这k个结点究竟是哪k个呢?

  • 很容易就能想到,是从7个结点中任意选k个结点,那么选法自然就有 C 7 k C^k_ {7} C7k​种,我们要做的就是一个一个遍历,一个一个判断这些选法是否合理,即是否连通

  • next_permutation()函数:将一个序列变成它的下一个排列(如果有),并返回真(大概)

  • 有了这个函数,就不必手动生成这些排列了,比较方便

  • 对于图,这里采用邻接矩阵存图,并初始化

  • 建立一个装“选法”的数组,储存每个节点“选”还是“不选”的状态

  • 判断某种选法是否合理

代码如下

#include <algorithm>
#include <iostream>
using namespace std;

//由于每个结点只有两个状态,故只需要布尔数组即可
bool map[7][7];//邻接矩阵
bool a[7];//储存状态的数组

//初始化邻接矩阵
void init() {
    map[0][1] = map[1][0] = 1;
    map[0][5] = map[5][0] = 1;
    map[1][2] = map[2][1] = 1;
    map[1][6] = map[6][1] = 1;
    map[2][3] = map[3][2] = 1;
    map[2][6] = map[6][2] = 1;
    map[3][4] = map[4][3] = 1;
    map[4][5] = map[5][4] = 1;
    map[4][6] = map[6][4] = 1;
    map[5][6] = map[6][5] = 1;
}

//装填每一种选法的“初始状态”
//其实就是为next_permutation函数服务的,因为这个函数转化的下一个排列是按照字典序从小到大排列的,所以要选第一个排列为起点
//如选4个结点,那么数组就要初始化为{0,0,0,1,1,1,1}
void put_in(int n) {
    fill(a, a + 7, false);
    fill(a + 7 - n, a + 7, true);
}

/**
 * @brief 判断图中给定的几个结点是否连通
 *
 * @param n 结点个数
 * @return true 连通
 * @return false 不连通
 */
bool is_connect(int n) {
    if (n == 1) return true;
    int cnt = 0;
    int tmp_cnt = 0;//某个结点与其它所有结点的“边数”
    int i = 0, j = 0;
    for (i = 0; i < 7; i++) {
        //剪枝,当结点i被选了才遍历其邻接点
        if (a[i]) {
            for (j = 0; j < 7; j++) {
                if (a[j] && map[i][j]) {
                    tmp_cnt++;
                }
            }
            if (!tmp_cnt) {
                return false;//如果某个结点不与任何其他结点邻接,则一定不连通
            } else {
                cnt += tmp_cnt;
                tmp_cnt = 0;
            }
        }
    }
    //由于每条边都计算了两次,所以最后的边数要除以2
    //至于为什么用这个条件,是因为“边数大于等于结点数-1的简单无向图一定是连通的”
    return (cnt / 2) >= (n - 1);
}

int main(void) {
    init();
    int cnt = 0;//合法的选法个数
    //选取的结点数从1到7遍历
    for (int i = 1; i <= 7; i++) {
        put_in(i);
        do {
            if (is_connect(i)) {
                cnt++;
            }
        } while (next_permutation(a, a + 7));//使用next_permutation函数
    }
    printf("%d\n", cnt);//输出结果
    return 0;
}

标签:map,结点,int,cnt,蓝桥,发光,七段
来源: https://blog.csdn.net/m0_52319522/article/details/122759594

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有