請你計算,一共有多少種不同的剪取方法。



我做這道題就用了兩個回溯(思路有點復雜)。。看來回溯對于藍橋杯很吃香啊。
1.首先用回溯從12個數里面找到5個數
2.每找到5個數把vist數組清0,并且把5個數的坐標分別寫入vist數組中
3.然后對vist數組進行回溯,看看從起點開始能不能走完5個數。可以就++否則繼續找別的5個數
對回溯不太了解的話可以先試著解決八皇后問題,很經典的題目
總體代碼需要改進還有很多
#include<iostream>using namespace std;int a[3][4] = { 0 };int v[13] = { 0 };int vist[3][4] = { 0 };int S = 0;int fz = 0;int q[3][4];int pd2(int i, int j){ if (i < 0 || j < 0 || i >= 3 || j >= 4 || a[i][j] == 0) return 0; return 1;}int pd3(int v[3][4]){ for (int i = 0; i < 3; i++){ for (int j = 0; j < 4; j++) { if (a[i][j] != 0){ if (v[i][j] == 0) return 0; } } } return 1;}void dfs(int i, int j){ if (pd3(vist)){//如果5個數對應的都為1,就滿足 fz = 1; return; } else{ if (vist[i][j] == 0){//經過判斷能到達的坐標都賦值為1 vist[i][j] = 1; if (pd2(i + 1, j)) dfs(i + 1, j); if (pd2(i - 1, j)) dfs(i - 1, j); if (pd2(i, j - 1)) dfs(i, j - 1); if (pd2(i, j + 1)) dfs(i, j + 1); } }}void f(int i, int j, int sum, int n){//尋找5個數的回溯方法 if (sum == 5){//找到5個數 int q1, q2; for (int i = 0; i < 3; i++){ for (int j = 0; j < 4; j++) if (a[i][j] != 0){//把第一個數的坐標記錄下來,做為下一個回溯的起點 q1 = i; q2 = j; break; } } for (int i = 0; i < 3; i++) for (int j = 0; j < 4; j++) vist[i][j] = 0;//每次vist清0 dfs(q1, q2); if (fz == 1){ S++; fz = 0; } } else{//進行回溯找到5個數 for (int k = n; k <= 12; k++){ if (v[k] == 0) { v[k] = 1; int q1, q2; for (int i = 0; i < 3; i++){//這點和乒乓球安排日程和方格填數就不一樣了 for (int j = 0; j < 4; j++) if (q[i][j] == k){//他不是像八皇后一樣每個位置的數都會變,他有固定的數,所以要把那個數對應的坐標記錄下來 q1 = i; q2 = j; } } a[q1][q2] = k; if (q2 == 3)//這點注意換行 f(q1 + 1, 0, sum + 1, k + 1); else f(q1, q2 + 1, sum + 1, k + 1); a[q1][q2] = 0; v[k] = 0; } } }}int main(){ int k = 0; for (int i = 0; i < 3; i++){ for (int j = 0; j < 4; j++) q[i][j] = ++k; }//先對數組賦值 f(0, 0, 0, 1); PRintf("%d", S); return 0;}代碼能改進的地方很多,希望大家指出。一起交流嘛
新聞熱點
疑難解答