什么是二进制枚举?
链接: 二进制枚举.
七段码
链接: 七段码.
这一题有点绕弯子了,代码修改了好一会
这里的判断条件稍微多一些。
整体思路就是:
- 枚举所有情况
- 对每种情况通过并查集判断是否连通
枚举的话我这里使用的是二进制枚举,优势就是比较快,不过这里既是填空题,总共又只有120来种情况,用DFS也是可以的
判断连通的话主要分为并和判断两方面
- 并:只要两个灯相连就合并。
在这里我考虑多了,由于我们是从前往后,且不重复判断的,不用考虑断掉或者是由于它有两端,头不一致的情况。
- 判断:我们把并查集整理好以后,只要pre[t]还是自己(t)的情况就是连在一起的一段(可以画图理解一下)。也就是说,段数有大于1,就不是连通的
完整代码
import java.util.Scanner;
public class test {
public static int count=0;
public static boolean[][] l = new boolean[8][8];
public static void init() {
l[1][1] = l[1][2]=l[1][6] = true;
l[2][2] = l[2][1]=l[2][7] = l[2][3]=true;
l[3][3] = l[3][2]=l[3][4] = l[3][7]=true;
l[4][4] = l[4][3]=l[4][5] = true;
l[5][5] = l[5][4]=l[5][7] = l[5][6]=true;
l[6][6] = l[6][1]=l[6][7] = l[6][5]=true;
l[7][7] = l[7][2]=l[7][3] = l[7][5]=l[7][6]=true;
}
public static void main(String[] args) {
init();
for(int i=0;i<(1<<7);i++) {
int[] light = new int[8];
for(int j=0;j<7;j++) {
if((i&(1<<j))>0) {
light[j+1]=1;
}
}
System.out.println();
if(check(light)) {
count++;
}
}
System.out.println(count);
}
public static boolean check(int[] lights) {
int i=1,j=1;
int[] pre= {0,1,2,3,4,5,6,7};
while(i<8) {
if(lights[i]==1) {
for(j=i+1;j<8;j++) {
if(lights[j]==1) {
if(l[i][j]) {
join(i,j,pre);
}
}
}
}
i++;
}
int count=0;
for(int t=1;t<8;t++) {
if(lights[t]==1&&pre[t]==t)
count++;
}
return count==1;
}
public static int find(int x,int[] pre) {
if(pre[x] == x) return x;
return pre[x] = find(pre[x],pre);
}
public static void join(int x,int y,int[] pre) {
int px = find(x,pre),py = find(y,pre);
if(px!=py)
pre[px] = py;
}
}