蓝桥杯剪邮票问题

首先题目是这样的:

剪邮票


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

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

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



题目要求的是求出所有满足条件的剪法,所以这里就用到组合问题,将所有的可能选出来,再一一进行判断,最终得出结果。

第一步:组合算法

void cbt(int low,int num){  //起始位与需要取出的个数   
if (num == 0) {  //出口
if (OK(c)) {   //判断c数组是否满足条件(代码见下文)
for (int i = 0; i < c.length; i++) {
System.out.print(c[i]+" ");
}
count++;
System.out.println();
}
}else{
for (int i = low; i < a.length; i++) {  //组合主体部分
c[num-1] = a[i];
cbt(i+1, num-1);
}
}
}

第二歩:判断条件

这里特殊说明一下,不是所有差值为1的2张邮票都是相连的,好比如4与5,为了防止太多的判断条件,所以将原数值进行修改

2 3 4

6 7 8 9

11 12 13 14

这样差值为1则一定在同一行,差值为5则一定在同一列。

boolean OK(int c[]){
boolean b = true;  //假定为与其他的邮票相连,若与其他4张邮票均不相连则false
int a[] = new int[5];//定义一个用来放连接数的数组(即该邮票与几张邮票相连)
int temp;//记录邮票相连的个数
for (int i = 0; i < c.length; i++) {
temp = 0;
for (int j = 0; j < c.length; j++) {
if (Math.abs(c[i]-c[j]) == 1||Math.abs(c[i]-c[j]) == 5) {//邮票相连的条件
temp++; 
}
}
if (temp == 0) {//如果temp为0  说明与其他4张邮票不相连,则排除(初步判断)
b = false;
}else {//否则就将相连个数记录
a[i] = temp;
}
}

//计算整个数组的相连数总数
int temp2 = 0;
for (int i = 0; i < a.length; i++) {
temp2+= a[i];
}
if (temp2 <= 6) {//如果相连数总数小于等于6,则一定不满足条件(再次判断)
b = false;
}
return b;
}

至于为什么第二次的判断条件是小于等于6。

其实很简单,第一次判断过后,唯独只有一种情况没有排除掉,如下图

下面是完整代码:

public class seven {

public static void main(String[] args) {

CBT c = new CBT();
c.cbt(0, 5);
System.out.println(c.count);
}
}


class CBT{
int a[] = {1,2,3,4,6,7,8,9,11,12,13,14};
int c[] = new int[5];
int count = 0;
void cbt(int low,int num){
if (num == 0) {
if (OK(c)) {
for (int i = 0; i < c.length; i++) {
System.out.print(c[i]+" ");
}
count++;
System.out.println();
}
}else{
for (int i = low; i < a.length; i++) {
c[num-1] = a[i];
cbt(i+1, num-1);
}
}
}

boolean OK(int c[]){
boolean b = true;
int a[] = new int[5];
int temp;
for (int i = 0; i < c.length; i++) {
temp = 0;
for (int j = 0; j < c.length; j++) {
if (Math.abs(c[i]-c[j]) == 1||Math.abs(c[i]-c[j]) == 5) {
temp++; 
}
}
if (temp == 0) {
b = false;
}else {
a[i] = temp;
}
}
int temp2 = 0;
for (int i = 0; i < a.length; i++) {
temp2+= a[i];
}
if (temp2 <= 6) {
b = false;
}

return b;
}
}

运行结果如下:(部分结果以及总数)


  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值