藍橋杯剪郵票問題

首先題目是這樣的:

剪郵票


如【圖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;
}
}

運行結果如下:(部分結果以及總數)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章