【问题描述】
小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有 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);
}
}
}
}