關於逆向思維在程式設計中的應用
阿新 • • 發佈:2019-02-19
眾所周知,逆向思維在知識領域一直倍受青睞,因為這種思想有時能夠很巧妙地解決一些看似很難的問題。更有人有此思想設計出強大的演算法,如回溯等。下面是一道例題:
[例] 編碼問題:設有一個數組A:ARRAY[0..N-1]OF INTEGER;陣列中儲存的元素為0-N-1之間的整數,且A[I]≠A[J] (當I≠J)時。
例如:N=6時,有:(4,3,0,5,1,2)
此時,陣列A的編碼定義如下:
A[0]的編碼為0:
A[I]的編碼為:在A[0],A[1],……A[I-1]中比A[I]的值小的元素的個數(I=1,2,……N-1)
所以上面陣列A的編碼為:B=(0,0,0,3,1,2)
程式要求解決以下問題
① 給出陣列A後,求出其編碼;
② 給出陣列A的編碼後,求出A的原資料。
[演算法設計] 問題①比較簡單,只要統計一下即可。問題②是一個線性表的刪除問題,將0到 N-1之間的N個整數順序放在一個線性表C中,取出編碼陣列B中的最後一個元素b[N-1],則C中的第b[N-1]個元素為陣列A的最後一個元素,取出該元素後從C中刪除之,再取編碼陣列B中的前一個元素,重複上述操作,直到陣列A的所有元素都得到為止。
下面是程式碼:
關於回溯的八皇后問題,以後可能會補充。#include <stdc.h>//萬能標頭檔案(自編,VS中沒有) int a[10000], b[10000], c[10000]; int arin(void) { int n = 0, i = 0; while (scanf("%d", &a[i]) == 1 && getchar() != '\n') { n++; i++; } return n + 1; }//讀入資料給陣列的函式 int main() { int n = arin(), i, j = 0, k = 0, m = 0; for (i = 0; i<n; i++) b[i] = 1; for (i = n - 1; i >= 0; i--) { m = 0; k = a[i] + 1; while (k > 0) { if (b[m] != 0) k--; m++; } b[m-1] = 0; c[j++] = m - 1; } for (i = n - 1; i >= 0; i--) printf("%d ", c[i]); return 0; }