2020蓝桥杯java组七段码(清晰易懂)

在这里插入图片描述

思路:

  • 乍一看这题思路还是挺清晰的,但是暴力写起来确实太考验code能力了
  1. 先将字母转化成0~6
  2. 先求出1~7个数的全排列(注意去重 1267 和1276 是一样的情况)
  3. 将7段码之间的关系构建邻接表
  4. 对第一步中求出的所有排列,进行连通性筛选(DFS和BFS和并查集都可以)
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

public class 七段码2 {
	static int count=0;
	static int[] visit=new int[7];
	static HashMap<Integer, List<Integer>> map=new HashMap<>();
	static HashSet<List<Integer>> set;
	public static void main(String[] args) {
	     //构建邻接表
		map.put(0,Arrays.asList(1,5)); 
		map.put(1,Arrays.asList(0,2,6));
		map.put(2,Arrays.asList(1,3,6));
		map.put(3,Arrays.asList(2,4));
		map.put(4,Arrays.asList(3,5,6));
		map.put(5,Arrays.asList(0,4,6));
		map.put(6,Arrays.asList(1,2,4,5));
		for (int k = 1; k <=7; k++) {
			set=new HashSet<>();
			for (int i = 1; i <=7; i++) {
				LinkedList<Integer> list = new LinkedList<Integer>();
				// 获取k个长度的排列,先排序后放入set去重
				dfs(k,list);
			}
			for (List<Integer> list: set) {
			    // 对set中的list进行连通性判断
				if (istrue(list)) {
					count++;
				}
			}
		}
		System.out.println(count);
	}
	private static void dfs(int num,LinkedList<Integer> list) {
		
		if (num==0) {
//			System.out.println(list+"----");
			List<Integer> list2 = list.stream().sorted().collect(Collectors.toList());
			set.add(list2);
			return;
		}
		
		for (int i = 0; i < 7; i++) {
			if (visit[i]==0) {
				visit[i]=1;
				list.addLast(i);
				dfs(num-1,list);
				list.removeLast();
				visit[i]=0;
			}
		}
		
	}
// bfs连通性判断
	private static boolean istrue(List<Integer> list) {
		// TODO Auto-generated method stub
		ArrayDeque<Integer> queue = new ArrayDeque<Integer>();
		boolean[] visit=new boolean[7];
		int cnt=0;
		// 注意获取的是元素,不是下标
		for (int i = 0; i <list.size(); i++) {
			int t0=list.get(i);// 获得当前元素
			queue.add(t0);
			if (!visit[t0]) {
				visit[t0]=true;
				cnt++;
				while(queue.size()>0) {
					List<Integer> list2 = map.get(queue.poll());// 获取当前元素映射的集合
					for (int j = 0; j <list.size(); j++) {// 遍历list里面的元素
						int t=list.get(j); // 获得list中的元素
						if (t0!=t&&!visit[t]&&list2.contains(t)) {
							visit[t]=true;
							queue.add(t);
						}
					}
				}
			}
		}
		return cnt==1;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值