於航特訓課第二課
藍橋杯算法特訓第二課【遞歸原理與構造技巧】源代碼
三月 7, 2018【內容簡介】
本文章內容為【2018藍橋杯大賽算法特訓(軟件)系列課程】第二課【遞歸原理與構造技巧】中涉及到的課上例題的代碼實現,加入賽前算法特訓獲取全部課程內容請聯系【小藍】。
【課程中涉及的源代碼】
1. 串的翻轉
【問題描述】
【源代碼】
【JAVA:於航】
1 2 3 4 5 6 7 8 9 10 11 |
public class A { static String f(String s){ if(s.length()<=1) return s; return f(s.substring(1)) + s.charAt(0); } public static void main(String[] args){ System.out.println(f("abcde")); } } |
【C:誌願者】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#define _CRT_SECURE_NO_WARNINGS #include #include #include char * f(char * s, int num) { if (num <= 1) { return s; } else { char *p = (char *)malloc(num+1); memset(p, 0, num+1); strcpy(p, s+1); char *pp = f(p, num-1); strcpy(p, pp); if (p!=pp) free(pp); strncpy(p+num-1,s,1); return p; } } void main() { char arr[100] = "abcde"; printf("%s", f(arr, 5)); } |
2. 循環改遞歸
【問題描述】
【源代碼】
【JAVA:於航】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class A { static void f(int a, int b){ for(int i=a; i<=b; i++){ System.out.println(i); } } static void g(int a, int b){ if(a<b) g(a,b-1); System.out.println(b); } public static void main(String[] args){ //f(1,10); g(1,10); } } |
【C語言:誌願者】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#define _CRT_SECURE_NO_WARNINGS #include #include #include void f2(int a, int b) { for (int i = a; i <= b; i++){ printf("%d ",i); } } void g2(int a, int b) { if (a < b) g2(a, b - 1); printf("%d ",b); } void main() { //f2(1,10); g2(1, 10); } |
3. 出棧次序
【問題描述】
X星球特別講究秩序,所有道路都是單行線。
一個甲殼蟲車隊,共16輛車,按照編號先後發車,夾在其它車流中,緩緩前行。
路邊有個死胡同,只能容一輛車通過,是臨時的檢查站,如圖所示。
X星球太死板,要求每輛路過的車必須進入檢查站,也可能不檢查就放行,也可能仔細檢查。
如果車輛進入檢查站和離開的次序可以任意交錯。那麽,該車隊再次上路後,可能的次序有多少種?
為了方便起見,假設檢查站可容納任意數量的汽車。
顯然,如果車隊只有1輛車,可能次序1種;2輛車可能次序2種;3輛車可能次序5種。
【源代碼】
【JAVA:於航】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/* 如果進棧次序為:1 2 3 4 5 。。。 出棧次序有多少種情況? */ public class A { // n 個等著進棧,棧中有m個 static int f(int n, int m) { if(n==0) return 1; if(m==0) return f(n-1,1); return f(n,m-1) + f(n-1, m+1); } static int f(int n) { return f(n, 0); } public static void main(String[] args) { for(int i=1; i<17; i++){ System.out.println(i + ": " + f(i)); } } } |
【C語言:誌願者】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#define _CRT_SECURE_NO_WARNINGS #include #include /* 如果進棧次序為:1 2 3 4 5 。。。 出棧次序有多少種情況? */ // n 個等著進棧,棧中有m個 int f3(int n, int m) { if (n == 0) return 1; if (m == 0) return f3(n - 1, 1); return f3(n, m - 1) + f3(n - 1, m + 1); } int f5(int n) { return f3(n, 0); } void main() { for (int i = 1; i<17; i++) { printf("%d : %d \n", i, f5(i)); } } |
4. 第39級臺階
【問題描述】
小明剛剛看完電影《第39級臺階》。離開電影院的時候,他數了數禮堂前的臺階數,恰好是39級!
站在臺階前,他突然又想著一個問題:
如果我每一步只能邁上1個或2個臺階。先邁左腳,然後左右交替,最後一步是邁右腳,也就是說一共要走偶數步。那麽,上完39級臺階,有多少種不同的上法呢?
請你利用計算機的優勢,幫助小明尋找答案。
【源代碼】
【JAVA:於航】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class A { // 奇數步 static long g(int n) { if(n==0) return 0; if(n==1) return 1; //if(n==2) return 1; return f(n-1) + f(n-2); } // 偶數步 static long f(int n) { if(n==0) return 1; if(n==1) return 0; //if(n==2) return 1; return g(n-1) + g(n-2); } public static void main(String[] args) { System.out.println(f(5)); System.out.println(f(39)); } } |
【C語言:誌願者】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#define _CRT_SECURE_NO_WARNINGS #include #include #include long ff(int n); // 奇數步 long gg(int n) { if (n == 0) return 0; if (n == 1) return 1; /*if(n==2) return 1;*/ return ff(n - 1) + ff(n - 2); } // 偶數步 long ff(int n) { if (n == 0) return 1; if (n == 1) return 0; /*if(n==2) return 1;*/ return gg(n - 1) + gg(n - 2); } void main() { printf("%d \n",ff(5)); printf("%d ", ff(39)); } |
5. 算式填符號
【問題描述】
匪警請撥110,即使手機欠費也可撥通!
為了保障社會秩序,保護人民群眾生命財產安全,警察叔叔需要與罪犯鬥智鬥勇,因而需要經常性地進行體力訓練和智力訓練!
某批警察叔叔正在進行智力訓練:
1 2 3 4 5 6 7 8 9 = 110
請看上邊的算式,為了使等式成立,需要在數字間填入加號或者減號(可以不填,但不能填入其它符號)。之間沒有填入符號的數字組合成一個數,例如:12+34+56+7-8+9 就是一種合格的填法;123+4+5+67-89 是另一個可能的答案。
請你利用計算機的優勢,幫助警察叔叔快速找到所有答案。
每個答案占一行。形如:
12+34+56+7-8+9
123+4+5+67-89
……
【源代碼】
【JAVA:於航】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class SuanShi { //a: 參加計算的元素 //k: 目前考慮的元素下標 //so: 合成好的結果串 //goal: 計算目標 static void f(int[] a, int k, String so, int goal){ if(k==0){ if(a[0] == goal){ System.out.println(a[0]+so); } return; } f(a,k-1,"+"+a[k]+so, goal-a[k]); f(a,k-1,"-"+a[k]+so, goal+a[k]); int old = a[k-1]; a[k-1] = Integer.parseInt("" + a[k-1] + a[k]); f(a,k-1,so,goal); a[k-1] = old; } public static void main(String[] args){ int[] a = {1,2,3,4,5,6,7,8,9}; f(a,8,"",110); } } |
【C語言:誌願者】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#define _CRT_SECURE_NO_WARNINGS #include #include #include //a: 參加計算的元素 //k: 目前考慮的元素下標 //so: 合成好的結果串 //goal: char void fk(int *a, int k, char *s, int goal){ if (k == 0){ if (a[0] == goal){ printf("%d%s\n",a[0],s); } return; } char * p = malloc(k * 2 + 1); memset(p, 0, k * 2 + 1); p[0] = ‘+‘; _itoa(a[k], p+1, 10); int x = strlen(p); strcat(p+x, s); fk(a, k - 1, p, goal - a[k]); p[0] = ‘-‘; fk(a, k - 1, p, goal + a[k]); int old = a[k - 1]; char ak[1024] = { 0 }; char ak2[1024] = { 0 }; _itoa(a[k - 1], ak, 10); _itoa(a[k], ak2, 10); strcat(ak, ak2); a[k - 1] = atoi(ak); memset(p, 0, k * 2 + 1); strcat(p, s); fk(a, k - 1, p, goal); a[k - 1] = old; } void main() { int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 } |