蓝桥杯java-B组2016年真题(剪邮票)及解题思路

剪邮票

题目描述:

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

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

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解题思路:

1.将12个序号存在数组numb中;

2.利用二维矩阵存放块与块之间的关系(0为不相邻,1位相邻)因为是对称的(1和2相邻等价于2和1相邻)所以存一半即可;

   1  2  3  4  5  6  7  8  9  10 11 12 
1  0  1  0  0  1  0  0  0  0  0  0  0 
2  0  0  1  0  0  1  0  0  0  0  0  0 
3  0  0  0  1  0  0  1  0  0  0  0  0 
4  0  0  0  0  0  0  0  1  0  0  0  0 
5  0  0  0  0  0  1  0  0  1  0  0  0 
6  0  0  0  0  0  0  1  0  0  1  0  0 
7  0  0  0  0  0  0  0  1  0  0  1  0 
8  0  0  0  0  0  0  0  0  0  0  0  1 
9  0  0  0  0  0  0  0  0  0  1  0  0 
10 0  0  0  0  0  0  0  0  0  0  1  0 
11 0  0  0  0  0  0  0  0  0  0  0  1
12 0  0  0  0  0  0  0  0  0  0  0  0 

3.递归求其子序列返回长度为5的子序列;

4.对子序列进行判断,如果5个相连,则count++;

5.输出count即为题解

代码实现:

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		String []numb ={"1 ","2 ","3 ","4 ","5 ","6 ","7 ","8 ","9 ","10 ","11 ","12 "};
		Integer [][]flog = new Integer[13][13];	//二维矩阵用来存块与块之间的连接关系
		for(int i=0;i<flog.length;i++) {	//将矩阵全部赋初值为0
			for(int j=0;j<flog[i].length;j++) {
				flog[i][j]=0;
			}
		}
		flog[1][2]=1;flog[1][5]=1;flog[2][6]=1;flog[2][3]=1;	//赋值相连的边为1
		flog[3][7]=1;flog[3][4]=1;flog[4][8]=1;
		flog[5][6]=1;flog[5][9]=1;flog[6][7]=1;flog[6][10]=1;
		flog[7][8]=1;flog[7][11]=1;flog[8][12]=1;
		flog[9][10]=1;flog[10][11]=1;
		flog[11][12]=1;
		List<String> list = new LinkedList<>();
		String s = "";
		subsequence(numb,list,0,s,0);
		int count =0;
		for(String i : list) {
			String []str = i.split(" ");
			Set<String> p = new HashSet<>(); // 集合用来判断是否连接,若链接加入set集合
			for(int m=0;m<str.length;m++) {
				for(int n=m;n<str.length;n++) {
					if(flog[Integer.parseInt(str[m])][Integer.parseInt(str[n])]==1) {
						p.add(str[m]);p.add(str[n]);
					}
				}
			}
			if(p.size()==5) {
				count++;
			}
		}
		System.out.println(count);
	}
	//求子序列函数返回长度为5的子序列
	public static void subsequence(String []numb,List<String> ans,int index,String s,int count) {
		if(index == numb.length) {
			if(count==5) {
				ans.add(s);
			}
			return;
		}
		String no = s;
		subsequence(numb,ans,index+1,no,count);
		String yes = s + String.valueOf(numb[index]);
		if(count<5) {
			subsequence(numb,ans,index+1,yes,count+1);
		}
	}
}

复杂度分析:

若是n张邮票,剪k张相连的。

其时间复杂度为:O(N*K^2),空间复杂度为:O(N)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杜柠函

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值