【蓝桥杯2020】 E题-七段码 枚举+dfs连通图

思路:枚举+dfs判断图是否连通

题目描述:

小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二
极管,分别标记为 a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符
的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上
一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光
的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?

答案:80
#include<iostream>
#include<cstring>
using namespace std;
int cnt = 0, ans = 0;
int a, b, c, d, e, f, g;
int maps[6][4], vis[6][4];
int dir[4][2] = { {-1,-1},{1,-1},{1,1},{-1,1} };//斜着走的四个方向
void init() {
	for (int i = 0; i < 6; i++) {
		for (int j = 0; j < 4; j++) {
			vis[i][j] = 1;
		}
	}
}
void creatMap() {
	maps[1][2] = a, maps[2][3] = b, maps[4][3] = c;
	maps[5][2] = d, maps[4][1] = e, maps[2][1] = f;
	maps[3][2] = g;//建图
				   /*
				   -1  a  -1
				   f  -1  b
				   -1  g  -1
				   e  -1  c
				   -1  d  -1
				   */
}
void dfs(int x,int y) {
	cnt--;//每访问一个相当于灭一盏灯
	vis[x][y] = 0;
	for (int i = 0; i < 4; i++) {
		int xx = x + dir[i][0];
		int yy = y + dir[i][1];
		if (maps[xx][yy] == 1 && vis[xx][yy] == 1)
			dfs(xx, yy);
	}

}

int main() {
	init();
	for (a = 0; a <= 1; a++)
	for (b = 0; b <= 1; b++)
	for (c = 0; c <= 1; c++)
	for (d = 0; d <= 1; d++)
	for (e = 0; e <= 1; e++)
	for (f = 0; f <= 1; f++)
		for (g = 0; g <= 1; g++) {
			//先枚举出每一种亮灯情况
			memset(maps, -1, sizeof(maps));
			creatMap();

			cnt = a + b + c + d + e + f + g;//总共亮灯的数目
			for (int i = 1; i < 6; i++)
				for (int j = 1; j < 4; j++) {
					if (maps[i][j] == 1) {
						init();
						dfs(i, j);//dfs判断是否连通
						if (maps[2][3] == 1 && maps[4][3] == 1 && cnt > 0)
							dfs(4, 3);
						if (maps[2][1] == 1 && maps[4][1] == 1 && cnt > 0)
							dfs(4, 1);
						if (cnt == 0) ans++;
						i = 6;
						break;//
					}
				}
		}
	cout << ans;
	return 0;
}

可能网上的更简洁吧!但我实在不甘心啊,所以废了好大功夫才把这敲了半截的代码完善好,毕竟这是我自己的思路,含着泪也要敲完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值