• 蓝桥杯——剪邮票(2016JavaB组第10题)


    剪邮票(16JavaB10)

    如【图1】, 有12张连在一起的12生肖的邮票。
    现在你要从中剪下5张来,要求必须是连着的。
    (仅仅连接一个角不算相连)
    比如,【图2】,【图3】中,粉红色所示部分就是合格的剪取。

    请你计算,一共有多少种不同的剪取方法。

    问题分析

    按题目,从1开始计数的话:
    |-同行:(id-1)÷4的结果相等,左右邻:相减±1
    |-同列:%4的结果相等,上下邻:相减±4

    使用深度优先遍历,

    深度优先:推进到底,触底再回

    比如:{3,5,6,7,10}

    先查找3跟{3,5,6,7,10}的谁相邻:
    3-X
    5-X
    6-X
    7-OK
    10-等待

    3-7匹配上了,继续推进,比较7和谁相邻(3已经比过了,算不匹配):
    3-X
    5-X
    6-OK
    7-等待
    10-等待

    7-6匹配上了,继续推进,比较6和谁相邻:
    3-X
    5-OK
    6-等待
    7-等待
    10-等待

    虽然6和10页相邻,但是”深度优先”,先推进下去,不管10。
    5没有再相邻的,所以回到6,再匹配到10。

    深度递归:
    |-先推进到底,走不通了再回头
    |-只要每个点都能走到,说明是连着的

    package bb;
    import java.util.HashSet;
    import java.util.Set;
    public class 剪邮票 {
    	private static boolean check(int a[]) {
    		boolean flag[] = new boolean[5];
    		dfs(a, flag, 0);
    		return flag[0] && flag[1] && flag[2] && flag[3] && flag[4];
    	}
    	// 深度优先搜索
    	private static void dfs(int a[], boolean[] flag, int n) {
    		flag[n] = true;
    		for (int i = 0; i < 5; i++) {
    			// 同行:(id-1)÷4的结果相等,左右邻:加减为1
    			// 不能用÷5,一行就4个(9÷5==1,10÷5==2)
    			if (!flag[i] && ((a[i] - 1) / 4 == (a[n] - 1) / 4)
    					&& (a[i] == a[n] - 1 || a[i] == a[n] + 1)) {
    				dfs(a, flag, i);
    			}
    			// 同列:%4的结果相等,上下邻:加减为4
    			if (!flag[i] && (a[i] % 4 == a[n] % 4) && (a[i] == a[n] - 4 || a[i] == a[n] + 4)) {
    				dfs(a, flag, i);
    			}
    		}
    	}
    	static Set<String> cutStamps() {
    		int[] a = new int[5];
    		Set<String> _set = new HashSet<String>();
    		int START = 0 + 1;
    		int END = 12 + 1;
    		for (a[0] = START; a[0] < END; ++a[0]) {
    			for (a[1] = a[0] + 1; a[1] < END; ++a[1]) {
    				for (a[2] = a[1] + 1; a[2] < END; ++a[2]) {
    					for (a[3] = a[2] + 1; a[3] < END; ++a[3]) {
    						for (a[4] = a[3] + 1; a[4] < END; ++a[4]) {
    							if (check(a)) {
    								_set.add("" + a[0] + " " + a[1] + " " + a[2] + " " + a[3] + " "
    										+ a[4]);
    							}
    						}
    					}
    				}
    			}
    		}
    		return _set;
    	}
    	public static void main(String[] args) {
    		Set<String> _set1 = cutStamps();
    		System.out.println(_set1.size());
    		System.out.println(_set1.contains("2 6 7 11 12"));
    		System.out.println(_set1.contains("3 5 6 7 10"));
    	}
    }
    
  • 相关阅读:
    ES6深入浅出-5 新版对象-1.如何创建对象
    ES6深入浅出-4 迭代器与生成器-5.科班 V.S. 培训
    ES6深入浅出-4 迭代器与生成器-4.总结
    ES6深入浅出-4 迭代器与生成器-3.生成器 & for...of
    ES6深入浅出-4 迭代器与生成器-2.Symbol 和迭代器
    Spring cloud微服务安全实战-3-2 第一个API及注入攻击防护
    Spring cloud微服务安全实战-3-1 API安全 常见的安全机制
    Spring Cloud微服务安全实战- 2-1 环境安装
    Spring cloud微服务安全实战_汇总
    ES6深入浅出-4 迭代器与生成器-1.字面量增强
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11190948.html
Copyright © 2020-2023  润新知