【蓝桥杯】七段码
作者:互联网
七段码
小蓝要用七段码数码管来表示一种特殊的文字。
图片描述
上图给出了七段码数码管的一个图示,数码管中一共有 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