題目
/* 剪郵票 如【圖1.jpg】, 有12張連在一起的12生肖的郵票。 現在你要從中剪下5張來,要求必須是連着的。 (僅僅連接一個角不算相連) 比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。 請你計算,一共有多少種不同的剪取方法。 請填寫表示方案數目的整數。 注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。 */
圖1.jpg
圖2.jpg
圖3.jpg
答案
116
代碼
1 public class Main { 2 static int cc[][] = { 3 {1,1,0,0,1,0,0,0,0,0,0,0}, 4 {1,1,1,0,0,1,0,0,0,0,0,0}, 5 {0,1,1,1,0,0,1,0,0,0,0,0}, 6 {0,0,1,1,0,0,0,1,0,0,0,0}, 7 {1,0,0,0,1,1,0,0,1,0,0,0}, 8 {0,1,0,0,1,1,1,0,0,1,0,0}, 9 {0,0,1,0,0,1,1,1,0,0,1,0}, 10 {0,0,0,1,0,0,1,1,0,0,0,1}, 11 {0,0,0,0,1,0,0,0,1,1,0,0}, 12 {0,0,0,0,0,1,0,0,1,1,1,0}, 13 {0,0,0,0,0,0,1,0,0,1,1,1}, 14 {0,0,0,0,0,0,0,1,0,0,1,1}, 15 }; 16 public static void main(String[] args) { 17 int a,b,c,d,e,sum=0; 18 for(a=0;a<8;a++) { 19 for(b=a+1;b<9;b++) { 20 for(c=b+1;c<10;c++) { 21 for(d=c+1;d<11;d++) { 22 for(e=d+1;e<12;e++) { 23 int z[] = {a,b,c,d,e}; 24 if(f(z)){ 25 System.out.println(a+1+" "+(b+1)+" "+(c+1)+" "+(d+1)+" "+(e+1)); 26 sum++; 27 } 28 } 29 } 30 } 31 } 32 } 33 System.out.println(sum); 34 } 35 private static boolean f(int[] a) { 36 int is[] = new int[5]; 37 is[0] = 1; 38 g(a,0,is); 39 int zz=0; 40 for(int i:is){ 41 if(i==1)zz++; 42 } 43 if(zz==5) return true; 44 return false; 45 } 46 private static void g(int[] a, int b, int[] c){ 47 for(int i=0;i<c.length;i++){ 48 if(c[i]==0){ 49 if(cc[a[b]][a[i]]==1){ 50 c[i] = 1; 51 g(a,i,c); 52 } 53 } 54 } 55 } 56 }
解析
這道題也是屬於排列組合的題,只不過不是前面的全排列,而是從12個數中無前后順序的抽取5個,然后判斷抽出的5個是否滿足要求,若是則計數++,否則return ;
我的解法思路是:用5個for循環嵌套來分別表示這從小到大的5個數,其中的條件也是互相有關聯的,用這種方法來抽取5個數並存入數組中,然后用f函數來驗證所抽取的是否滿足條件,g方法的作用是深度遍歷,從數組中第一個數開始按照條件向 足相鄰條件的那一項 遍歷,並且用is[]數組來做標記,當這一次遍歷結束時,判斷是否全部遍歷,如果是則滿足條件return true,否則沒有
return false;
在判斷是否滿足相鄰關系的那個地方,因為覺得找出邏輯關系很麻煩,所以就自己手動寫了一個二位數組,用來判斷從1-12,這12個數的兩兩相鄰情況,1則相鄰,0則不相鄰。
1是因為懶,2是因為方便,省時間
可以充分的把一些不是怎么變的東西,用人腦來完成