蓝桥杯真题——剪邮票

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

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

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个题目有点像迷宫问题,一开始想的是用dfs算法去遍历出所有的5段长的路径,可是不知道怎么去重。后来还是借助了csdn上的大佬的思路来解题

这个题的规模较小,所以我们可以对1到12暴力枚举出含有5个数的所有组合,然后对每一个组合进行连通性检测,如果是连通的则进行累加。

明白了解题思路之后,来看一下代码实现:

首先需要暴力枚举出所有组合:

public static void main(String[] args) {
    
    
	int count=0;
	for(a[0] = 0;a[0]<12;a[0]++)
		for(a[1] = a[0]+1;a[1]<12;a[1]++)
			for(a[2] = a[1]+1;a[2]<12;a[2]++)
				for(a[3] = a[2]+1;a[3]<12;a[3]++)
					for(a[4] = a[3]+1;a[4]<12;a[4]++)
					{
    
    
						if(judge())   这个是后面判断连通性的函数
							count++;
					}
 System.out.println(count);
 }

判断连通性需要先建立一个布尔类型的visit[5]的数组,用dfs去找所有的点,找到的话就把对应的visit置true,遍历完之后,如果是连通的则visit数组全部为true。

private static boolean judge() {
    
    
	boolean visit[] = new boolean [5];
	dfs(visit,0);
	return visit[0]&&visit[1]&&visit[2]&&visit[3]&&visit[4];
}

找点是有规律的,同一行的两个点连接的话,它们的数值是相差1的。同一列的两个点连接的话,它们的数值是相差4的。

private static void dfs(boolean[] visit, int i) {
    
    
    visit[i] = true;                    每次进入一个新的点就把visit置为true
    for(int j=0;j<visit.length;j++) {
    
    
    	if(!visit[j]&&(a[i]/4==a[j]/4)&&(a[i]-1==a[j] || a[i]+1==a[j]))  判断同一行的且相差1dfs(visit,j);
    	if(!visit[j]&&(a[i]%4==a[j]%4)&&(a[i]-4==a[j] || a[i]+4==a[j]))  判断同一列的且相差4dfs(visit,j);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44919936/article/details/111651681
今日推荐