小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有7 段可以发光的二极管,分别标记为a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
思路:并没有用并查集和dfs,这里使用了图的基础知识,先进行连线,将有交点的字母用数组存储,然后"abcdefg"这几种字符串找他的所有子集,即是所有的发光可能性,然后依次遍历他的子集,我发现了一个规律,如(abc)这三个发光,那么ab,bc可以判断连通,那么可以设置一个计数器,如果sum>=子集长度-1的话,就说明是连通的。
这样跑出来是82种,我找了很久发现,当有环的时候上面那个规律不成立,所以我们减去两次出现环的可能,得到80种就为正确答案。
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int map[][]=new int[8][8];
map[1][1]=1;map[1][2]=1;map[1][6]=1;
map[2][1]=1;map[2][2]=1;map[2][3]=1;map[2][7]=1;
map[3][2]=1;map[3][3]=1;map[3][4]=1;map[3][7]=1;
map[4][3]=1;map[4][4]=1;map[4][5]=1;
map[5][4]=1;map[5][5]=1;map[5][6]=1;map[5][7]=1;
map[6][1]=1;map[6][5]=1;map[6][6]=1;map[6][7]=1;
map[7][1]=1;map[7][2]=1;map[7][6]=1;map[7][7]=1;
ArrayList<String> arr=zixu();
int num=0;
for (String s:arr)
{
if(s.equals("12467")||s.equals("13457"))
{
continue;
}
char[] temp = s.toCharArray();
if(temp.length==1)
{
num++;
}
else{
int sum=0;
for (int i = 0; i <temp.length-1; i++) {
for (int j = i+1; j <temp.length; j++) {
if(map[temp[i]-'0'][temp[j]-'0']==1)
{
sum++;
}
}
}
if(sum>=temp.length-1)
{
num++;
}
}
}
System.out.println(num);
}
public static ArrayList<String> zixu()
{
ArrayList<String> arr = new ArrayList<>();
String str="1234567";
char s[]=str.toCharArray();
f(0,"",s,arr);
return arr;
}
public static int f(int k,String s,char str[],ArrayList<String> arr)
{
if(k==str.length)
{
if(s!="")arr.add(s);
return 0;
}
f(k+1,s,str,arr);
f(k+1,s+str[k],str,arr);
return 0;
}
}