蓝桥杯 2020 D 七段码

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

上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二 极管,分别标记为 a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符 的表达时,要求所有发光的二极管是连成一片的。
例如: b 发光,其他二极管不发光可以用来表达一种字符。
例如: c 发光,其他二极管不发光可以用来表达一种字符。这种 方案与上 一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如: a, b, c, d, e 发光, f, g 不发光可以用来表达一种字符。
例如: b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光 的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路:
7
把7条边组合求出来(共127种 Σ C7i)c71+c72+…c77
i=1
将7条边转化为图,固定格式为6个点。

查看转化完的图是否为连通图,连同则ans++

package blueAgroup;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class 七段码 {
	static Character[] arr = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
	static List<Character> list = new LinkedList<Character>();
	static int ans = 0;
	static boolean[] vis;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		for (int i = 1; i <= 7; i++) {
			dfs(0, 0, i);
		}
		System.out.println(ans);

	}
    //将七段码进行组合。
	private static void dfs(int i, int j, int exit) {
		if (exit == i) {
			if (check(list))
				ans++;
			return;
		}
		if (j == arr.length)
			return;
		list.add(arr[j]);
		dfs(i + 1, j + 1, exit);
		list.remove(arr[j]);
		dfs(i, j + 1, exit);

	}
    //先将七条边表示成图,(点数跟边数不同  两个概念)再去检查图是否连同,连通则ans++
	private static boolean check(List<Character> list2) {
		int[][] graph = new int[6][6];
		for (int i = 0; i < list2.size(); i++) {
			switch (list2.get(i)) {
			case 'a': {
				graph[0][1] = graph[1][0] = 1;
			}
				break;
			case 'b': {
				graph[1][2] = graph[2][1] = 1;
			}
				break;
			case 'c': {
				graph[2][3] = graph[3][2] = 1;
			}
				break;
			case 'd': {
				graph[3][4] = graph[4][3] = 1;
			}
				break;
			case 'e': {
				graph[4][5] = graph[5][4] = 1;
			}
				break;
			case 'f': {
				graph[5][0] = graph[0][5] = 1;
			}
				break;
			case 'g': {
				graph[2][5] = graph[5][2] = 1;
			}
				break;

			default:
				throw new IllegalArgumentException("Unexpected value: " + list2.get(i));
			}
		}
		//计算图的点数。set.size()就是点的数量,set有去重的特性。
		Set<Integer> set = new HashSet<Integer>();
		for (int i = 0; i < graph.length; i++) {
			for (int j = 0; j < graph[i].length; j++) {
				if (graph[i][j] == 1) {
					set.add(i);
					set.add(j);
				}

			}
		}
		
		vis = new boolean[6];
		//递归查看点时候被访问过(起始点是该图任意一个点)。。
		it:for (int i = 0; i < graph.length; i++) {
			for (int j = 0; j < graph[i].length; j++) {
				if (graph[i][j] == 1) {
					dfs2(graph, i);
					break it;//跳出所有的循环
				}
			}
		}
        //查看有多少个点被访问过。
		int flag = 0;

		for (int i = 0; i <6; i++) {
			if (vis[i])
				flag++;
		}
		for (int j = 0; j < graph.length; j++) {
			System.out.print("第" + j + "个" + vis[j] + " ");
		}
		System.out.println(list2);
		System.out.println("点的个数:" + set.size());
		System.out.println("flag:" + flag);
        //如果被访问过的点与图的总点数相同,则证明是连通图。
		if (flag == set.size()) {
			return true;
		}


		return false;
	}
    //递归访问图。
	private static void dfs2(int[][] graph, int i) {
		vis[i]=true;
		for (int k = 0; k < graph.length; k++) {
			if (graph[i][k] == 1 && !vis[k]) {
				dfs2(graph, k);
			}
		}

	}

}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值