【每日蓝桥】40、一六年省赛Java组真题“剪邮票”

你好呀,我是灰小猿,一个超会写bug的程序猿!

欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!

标题:剪邮票

如【图1.jpg】有12张连在一起的十二生肖的邮票

现在你要从中剪下五张来,要求五张必须是连续的

【只连接一个角不算连接】

如【图2.jpg】和【图3.jpg】中的粉色部分就是合格的剪取

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

请填写表示方案数目的整数,

注意:你提交的应该是一个整数,不要填写任何多余内容或说明性文字

解题思路:

本题在求解上的思路是:首先将12个元素标记出来,粉色格子标记为1,白色格子标记为0,那么我们可以假设数组是{0,0,0,0,0,0,0,1,1,1,1,1},可以理解为对这12个元素进行全排列,由于存在重复元素,因此在排列之后,需要去除重复排列,然后将结果映射成二维数组,判断该二维数组的连通性,如果连通性为1,则符合要求,否则不符合要求,结果不加一。

答案源码:

package 一六年省赛真题;

import java.util.HashSet;

public class Year2016_Bt7 {

	static HashSet<String> hashSet = new HashSet<String>();
	static int ans = 0;
	public static void main(String[] args) {
		int [] arr = {0,0,0,0,0,0,0,1,1,1,1,1};
		f(arr, 0);
		System.out.println(ans);
	}
	
	public static void f(int [] arr,int k) {
		if (k == arr.length) {
			//如果hashset中不包含已经排列好的数组,则进行连通性判断
//			System.out.println(hashSet.add(arrToStr(arr)));
			if (hashSet.add(arrToStr(arr))) {
				//如果连通,则答案加一
				if (check(arr)) {
					ans++;
				}
			}
			return;
		}
		
		for (int i = k; i < arr.length; i++) {
			
			int t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
			
			//递归确定下一个元素
			f(arr, k+1);
			
			//回溯
			t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
		}
	}
	
	//数组
	private static String arrToStr(int[] arr) {
		String s = "";
		for (int i : arr) {
			s += i;
		}
		return s;
	}

	/**
	 * 判断数组构成的二维数组是否具有连通性
	 * */
	private static boolean check(int[] arr) {
		int [][] matrix = new int[3][4];
		//将一维数组映射成二维数组
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 4; j++) {
				if (arr[i*4+j]==1) {
					matrix[i][j] = 1;
				}else {
					matrix[i][j] = 0;
				}
			}
		}
		int count = 0;
		//从二维数组的每一个元素开始进行连通性判断
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 4; j++) {
				if (matrix[i][j]==1) {
					dfs(matrix,i,j);
					count++;
				}		
			}	
		}
		//如果只有一个连通图,则该情况成立
		return count==1;
	}

	//对元素进行深搜
	private static void dfs(int[][] matrix, int i, int j) {
		matrix[i][j] = 0;
		//对该坐标的四个方向进行判断,如果某个方向可以走,并且该方向上的那个坐标值是1,则走到这一个格
		if(i-1>=0&&matrix[i-1][j]==1) dfs(matrix, i-1, j);
		if(i+1<=2&&matrix[i+1][j]==1) dfs(matrix, i+1, j);
		if(j-1>=0&&matrix[i][j-1]==1) dfs(matrix, i, j-1);
		if(j+1<=3&&matrix[i][j+1]==1) dfs(matrix, i, j+1);	
	}

}

输出样例:

其中有不足或者改进的地方,还希望小伙伴留言提出,一起学习!

感兴趣的小伙伴可以关注专栏!

灰小猿陪你一起进步!

猜你喜欢

转载自blog.csdn.net/weixin_44985880/article/details/115095002