1. 程式人生 > >關於逆向思維在程式設計中的應用

關於逆向思維在程式設計中的應用

眾所周知,逆向思維在知識領域一直倍受青睞,因為這種思想有時能夠很巧妙地解決一些看似很難的問題。更有人有此思想設計出強大的演算法,如回溯等。下面是一道例題:

[例] 編碼問題:設有一個數組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;
}
關於回溯的八皇后問題,以後可能會補充。