题目描述
小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,
数码管中一共有7 段可以发光的二极管,分别标记为a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。 例如:b
发光,其他二极管不发光可以用来表达一种字符。 例如:c
发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。 例如:a, b, c, d,
e 发光,f, g 不发光可以用来表达一种字符。 例如:b, f
发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。 请问,小蓝可以用七段码数码管表达多少种不同的字符?
输出格式
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只输出这个整数,输出多余的内容将无法得分。
答案:80
结题思路
- 首先,这是一个图问题,存储方式为邻接矩阵,我们使用
0~ 6
来表示a ~g
,然后使用二维的布尔数组arr
表示邻接矩阵,相邻则为true
arr = new boolean[7][7];
// a b c d e f g
// 0 1 2 3 4 5 6
arr[0][1] = arr[0][5] = true;
arr[1][0] = arr[1][2] = arr[1][6] = true;
arr[2][1] = arr[2][3] = arr[2][6] = true;
arr[3][2] = arr[3][4] = true;
arr[4][3] = arr[4][5] = arr[4][6] = true;
arr[5][0] = arr[5][4] = arr[5][6] = true;
arr[6][1] = arr[6][2] = arr[6][4] = arr[6][5] = true;
- 我们使用列表
path
存储已经走过的节点,那么不在path
中的节点就是未走过的节点
private static List<Integer> path = new LinkedList<>();
- 从每个顶点出发,采用
DFS
(深度优先搜索)策略遍历未走过的节点
for (int i = 0; i < 7; i++) {
path.clear();//path存储已走过的节点
path.add(i);//从顶点i出发
add_result(path, set);//一个节点也作为一种方案
dfs(path);// dfs剩余节点
}
private static void dfs(List<Integer> path) {
for (int j = 0; j < 7; j++) {
if (!path.contains(j)&&isOK(path, j)) {//path中没有j且可达j
path.add(j);
add_result(path, set);
dfs(path);
path.remove(path.indexOf(j));//还原path操作
}
}
}
-
对于每一个节点
j
,如果j
未走过且可达[isOK函数
],j
加入path
,作为一种方案,并从这里dfs。还原path
,判断j+1
。 -
每走一步,更新
path
,将path
排序后以字符串方式存储于set
中,因为set
的性质,不会存储相同的字符串,即不会存储相同的方案 -
set
的大小就是不同方案的个数
完整代码
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class Main{
private static boolean[][] arr;
private static List<Integer> path = new LinkedList<>();
private static Set<String> set = new HashSet<>();
public static void main(String[] args) {
arr = new boolean[7][7];
// a b c d e f g
// 0 1 2 3 4 5 6
arr[0][1] = arr[0][5] = true;
arr[1][0] = arr[1][2] = arr[1][6] = true;
arr[2][1] = arr[2][3] = arr[2][6] = true;
arr[3][2] = arr[3][4] = true;
arr[4][3] = arr[4][5] = arr[4][6] = true;
arr[5][0] = arr[5][4] = arr[5][6] = true;
arr[6][1] = arr[6][2] = arr[6][4] = arr[6][5] = true;
for (int i = 0; i < 7; i++) {
path.clear();
path.add(i);
add_result(path, set);
dfs(path);// 从i出发
}
System.out.println(set.size());
}
private static void dfs(List<Integer> path) {
for (int j = 0; j < 7; j++) {
if (!path.contains(j) && isOK(path, j)) {// path中没有j且可达j
path.add(j);
add_result(path, set);
dfs(path);
path.remove(path.indexOf(j));
}
}
}
private static boolean isOK(List<Integer> path, int j) {// path是否可达j
for (int i : path) {
if (arr[i][j])
return true;
}
return false;
}
private static void add_result(List<Integer> path, Set<String> set) {// 新增结果
path.sort(null);// 先排序,顺序不一样但内容一样作为一种方案
String s = "";
for (int i = 0; i < path.size(); i++) {
s += (char) (path.get(i) + 'a');
}
set.add(s);
}
}
OK,结束啦,欣赏下美景吧