編程題#1: 完美覆蓋
來源: POJ (Coursera聲明:在POJ上完成的習題將不會計入Coursera的最后成績。)
注意: 總時間限制: 1000ms 內存限制: 65536kB
描述
一張普通的國際象棋棋盤,它被分成 8 乘 8 (8 行 8 列) 的 64 個方格。設有形狀一樣的多米諾牌,每張牌恰好覆蓋棋盤上相鄰的兩個方格,即一張多米諾牌是一張 1 行 2 列或者 2 行 1 列的牌。那么,是否能夠把 32 張多米諾牌擺放到棋盤上,使得任何兩張多米諾牌均不重疊,每張多米諾牌覆蓋兩個方格,並且棋盤上所有的方格都被覆蓋住?我們把這樣一種排列稱為棋盤被多米諾牌完美覆蓋。這是一個簡單的排列問題,同學們能夠很快構造出許多不同的完美覆蓋。但是,計算不同的完美覆蓋的總數就不是一件容易的事情了。不過,同學們 發揮自己的聰明才智,還是有可能做到的。
現在我們通過計算機編程對 3 乘 n 棋盤的不同的完美覆蓋的總數進行計算。
任務
對 3 乘 n 棋盤的不同的完美覆蓋的總數進行計算。
輸入
一次輸入可能包含多行,每一行分別給出不同的 n 值 ( 即 3 乘 n 棋盤的列數 )。當輸入 -1 的時候結束。
n 的值最大不超過 30.
輸出
針對每一行的 n 值,輸出 3 乘 n 棋盤的不同的完美覆蓋的總數。
樣例輸入
2 8 12 -1
樣例輸出
3 153 2131
遞歸表達式想了很久沒想出來,用了網上這個論文的http://www.cnblogs.com/drizzlecrj/archive/2008/12/23/1360670.html
1 #include <iostream> 2 using namespace std; 3 4 int horizontal(int n); 5 int vertical(int n); 6 7 int count(int n) { 8 if (n == 0) return 1; 9 if(n % 2) return 0; 10 return horizontal(n)+vertical(n); 11 } 12 13 int horizontal(int n) { 14 if (n == 0) return 1; 15 if (n == 1) return 0; 16 return 2 * vertical(n-1) + horizontal(n-2); 17 } 18 19 int vertical(int n) { 20 if (n == 0) return 0; 21 if (n == 1) return 1; 22 return horizontal(n-1) + vertical(n-2); 23 } 24 25 int main() 26 { 27 int n; 28 cin >> n; 29 while (n != -1) { 30 cout<<count(n); 31 cin>>n; 32 if (n != -1) cout<<endl; 33 } 34 return 0; 35 }
