七段码(蓝桥杯)

2024-03-27 12:52
文章标签 蓝桥 七段

本文主要是介绍七段码(蓝桥杯),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 七段码
    • 题目描述
    • 答案:80
    • 分析
      • 编程求解:有多种方法
        • 方法一:状态压缩+枚举+构图(以二极管为顶点)+DFS判断连通
        • 代码
        • 方法二:bfs

七段码

题目描述

小蓝要用七段码数码管来表示一种特殊的文字。
在这里插入图片描述

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

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

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

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

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

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

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

答案:80

分析

手工求解:容易遗漏,本题不宜采用。

编程求解:有多种方法

方法一:状态压缩+枚举+构图(以二极管为顶点)+DFS判断连通
  1. 状态压缩:一共才7段二极管,每段二极管都可以选或不选(全部不选不行),所以总共有27-1=127种方案,把1~127范围内的每个数转换成二进制,就对应到一种方案。
    例如,(23)10=(0010111)2,表示a,b,c,e选,其他二极管不选。
  2. 枚举每个方案,看是否符合要求。
  3. 构图:以二极管为顶点,二极管相邻则连边。
  4. DFS判断连通:对每一种方案,从该方案中任何一个选中的顶点出发进行DFS,跳过那些没有选中的顶点,DFS完毕,如果所有选中的顶点都遍历到,则说明是连通的,是一种符合题目要求的方案。

在这里插入图片描述

方法重点:DFS、构图。
特征:方案,计数
核心思路:枚举所有方案,对预设的方案,通过关联等条件搜索DFS能覆盖此方案中所有亮的二极管,那么此方案计入方案数。

代码

这段代码的目的是计算可以用七段数码管表示的、所有发光的二极管连成一片的不同字符的数量。下面是对代码的详细注释:

#include<bits/stdc++.h>
using namespace std;// 定义七段数码管中各个段之间的连接关系
int g[7][7] = {0,1,0,0,0,1,0, // a段1,0,1,0,0,0,1, // b段0,1,0,1,0,0,1, // c段0,0,1,0,1,0,0, // d段0,0,0,1,0,1,1, // e段1,0,0,0,1,0,1, // f段0,1,1,0,1,1,0  // g段
};// d数组用于标记当前方案中哪些段是亮的
int d[7];
// v数组用于标记在深度优先搜索中已经访问过的段
int v[7];// 深度优先搜索函数,用于搜索所有与start相连的亮段
void dfs(int start) {for(int i = 0; i < 7; i++) {// 如果当前段i与start相连,且i段是亮的,且之前没有访问过i段if(g[start][i] == 1 && d[i] == 1 && v[i] == 0) {v[i] = 1; // 标记i段为已访问dfs(i); // 递归调用dfs,继续搜索从i段出发的相连亮段}}
}int main() {int ans = 127; // 初始化答案为所有可能的组合数,即2^7 - 1(减1是因为至少有一个段是亮的)for(int i = 1; i <= 127; i++) { // 遍历所有可能的组合memset(d, 0, sizeof(d)); // 重置d数组为全0,表示所有段初始都是灭的memset(v, 0, sizeof(v)); // 重置v数组为全0,表示没有段被访问过int x = i, j = 0; // x为当前二进制数,j为当前位的索引// 将i的二进制表示分解为一个个位,并存储到d数组中while(x) {d[j++] = x % 2; // 存储当前位的亮灭状态x /= 2; // 移除已处理的位}// 找到第一个亮的段作为搜索的起点int start = 0;while(d[start] == 0) start++;v[start] = 1; // 标记起点为已访问dfs(start); // 从起点开始深度优先搜索// 检查是否所有的亮段都已经被访问过for(int j = 0; j < 7; j++) {if(d[j] == 1 && v[j] == 0) {ans--; // 如果有亮的段没有被访问过,说明当前方案不合法,答案减一break; // 跳出循环,继续下一个组合}}}cout << ans; // 输出最终的合法组合数return 0;
}

这段代码通过二进制的方式来表示每个字符的七段数码管的亮灭状态,然后通过深度优先搜索(DFS)来检查每个可能的组合是否满足题目中的条件(所有发光的二极管是连成一片的)。如果一个组合不满足条件,它会被排除,最终输出符合条件的字符数量。

方法二:bfs

这段代码的目的是使用广度优先搜索(BFS)来解决一个问题,具体来说,是计算在一个给定的图形(由七个点组成)中,有多少种方式可以使得所有点亮的点连成一片。这个问题可以通过检查每个点的连接性来解决。下面是对代码的详细注释:

#include<bits/stdc++.h>
using namespace std;// ans用于记录连成一片的点亮点的数量
int ans;
// g[7][7]是一个二维数组,用于表示图形中点之间的连接关系
int g[7][7];
// vis[7]是一个数组,用于标记在BFS过程中已经访问过的点
int vis[7];
// flag[7]是一个数组,用于标记在检查过程中哪些点是亮的
int flag[7];// BFS函数用于广度优先搜索,确定一个点是否连通其他亮的点
void bfs(int x){queue<int> que; // 定义一个队列用于BFSque.push(x); // 将起点x入队vis[x] = true; // 标记x为已访问while(!que.empty()){ // 当队列不为空时循环int u = que.front(); // 取出队列前端的点que.pop(); // 将该点从队列中移除for(int i = 0 ; i <= 6 ; i ++){ // 遍历所有与u相连的点if(g[u][i] && flag[i] && !vis[i]){ // 如果该点与u相连,且该点是亮的,且未被访问过vis[i] = true; // 标记为已访问que.push(i); // 将该点入队,继续BFS}}}
}// check函数用于检查一个给定的二进制编码x是否表示一个连通的图形
bool check(int x){for(int i = 0 ; i <= 6 ; i ++) // 初始化flag和vis数组flag[i] = vis[i] = false;int cnt = 0; // 用于计数连通分量的数量for(int i = 6 ; ~i ; i --) // 遍历x的每一位if(x >> i & 1) flag[i] = true; // 如果某一位为1,则标记对应的点为亮的for(int i = 0 ; i <= 6 ; i ++){ // 再次遍历每个点if(flag[i] && !vis[i]){ // 如果点是亮的,但还未被访问bfs(i); // 执行BFScnt ++ ; // 连通分量数量加一}}return cnt == 1; // 如果只有一个连通分量,返回true
}int main()
{// 初始化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;// 遍历所有可能的二进制编码(0到127)for(int i = 0 ; i < (1 << 7) ; i ++){if(check(i)) { // 如果当前编码表示一个连通的图形ans ++ ; // 答案加一}}cout << ans << '\n'; // 输出答案return 0;
}

这段代码通过二进制编码来表示每个点的亮灭状态,然后使用BFS来检查每个点是否连通其他亮的点。check函数用于确定一个给定的编码是否表示一个连通的图形。如果是,那么答案ans就会增加。最后,程序输出所有可能的连通图形的数量。

这篇关于七段码(蓝桥杯)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/852165

相关文章

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_s

基于MicroPython的ESP8266控制七段数码管的设计方案

以下是一个基于MicroPython的ESP8266控制七段数码管的设计方案: 一、硬件准备 1. ESP8266开发板(如NodeMCU)             2. 七段数码管(共阳或共阴型)                      3. 限流电阻(根据数码管的电流要求选择合适的阻值

找不同-第15届蓝桥省赛Scratch初级组真题第4题

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第183讲。 如果想持续关注Scratch蓝桥真题解读,可以点击《Scratch蓝桥杯历年真题》并订阅合集,查阅教程更方便。 第15届蓝桥杯省赛已于2024年8月24日落下帷幕,编程题一共有5题,分别如下: 猪八戒落地 游乐场 画西瓜 找不同 消

【蓝桥杯嵌入式(一)程序框架和调度器】

蓝桥杯嵌入式(一)程序框架和调度器 序、代码命名规则零、STM32和8051⼀、软件及环境安装⼆、⼯程框架搭建1.时钟配置2、SYS配置3、⼯程配置4、NVIC配置5.、Keil配置 三、系统初始化四、任务调度器 链接: 视频出处 序、代码命名规则 以下是一些常见的举例 零、STM32和8051 链接: 8位和32位单片机最本质区别 ⼀、软件及环境安装

【蓝桥杯嵌入式(二)Led、Key、Lcd】

蓝桥杯嵌入式(二)Led、Key、Lcd 五、Led模块1.原理图配置2. 知识点3.底层代码 六、Key模块1.原理图配置2.知识点3.底层代码底层代码(四⾏代码版本)底层代码(状态机版本) 七、LCD模块1.原理图配置2.知识点底层代码 五、Led模块 1.原理图配置 2. 知识点 链接: 上拉电阻的通俗解释 链接: 单⽚机怎么输出⾼电平!推挽输出和开

蓝桥杯:整数删除

// 蓝桥杯整数删除.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include<stdio.h>#define MAX 100void findmin(int a[],int n,int& pos){int min=a[0];pos=0;//pos=0我开始忘了,特别注意

第十五届蓝桥杯图形化省赛题目及解析

第十五届蓝桥杯图形化省赛题目及解析 一. 单选题 1. 运行以下程序,角色会说( )? A、29     B、31     C、33     D、35 正确答案:C 答案解析: 重复执行直到m>n不成立,即重复执行直到m<=n。所有当m小于或者 等于n时,循环结束。循环过程中变量m与变量n的变化如下表: 通过上述表格可知,循环到第五次循环结束。m的值为14,n的值为19

第八届蓝桥杯 最大公共子串(动态规划)

标题:最大公共子串 最大公共子串长度问题就是: 求两个串的所有子串中能够匹配上的最大长度是多少。 比如:"abcdkkk" 和 "baabcdadabc", 可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。 下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。 请分析该解法的思路,并补全划线部分缺失的代码。 #include <stdio.h

蓝桥杯第八届 方格分割(dfs)

标题:方格分割6x6的方格,沿着格子的边线剪开成两部分。要求这两部分的形状完全相同。如图:p1.png, p2.png, p3.png 就是可行的分割法。试计算:包括这3种分法在内,一共有多少种不同的分割方法。注意:旋转对称的属于同一种分割法。请提交该整数,不要填写任何多余的内容或说明文字。   观察可得他是一个中心对称图形,我们只需要搜索它的对称线即可。我们可以把对称线抽象为从(

蓝桥杯备赛day02:递推

斐波那契数列 #include <bits/stdc++.h>using namespace std;int main(){int n;cin>>n;int dp[n+1];dp[1]=1;dp[2]=1;for(int i = 3;i <= n;i++) dp[i] = dp[i-1]+dp[i-2];cout<<dp[n];return 0;} n = int(input())