殘缺棋盤問題



殘缺棋盤問題


對於1*1 2*2 4*4 8*8等 2^k*2^k的棋盤來說,都存在一個任意的位置,而在棋盤剩餘位置都可以用一個或多個由三個格子組成的L型直角版覆蓋
那麼如何覆蓋呢?
在這裏 採用分而治之的方法來考慮。
對於已知的殘缺位置,一定處於當前棋盤的某個象限,那麼在剩下的三個象限中在連接的地方各取一個方塊爲殘缺,這三個方塊的位置剛好可以構成
一個L型直角,而對於每個象限而言又是規定了一個殘缺位置,這樣與初始狀態又一致了。也就是說,將一個完整的棋盤不斷地化爲四份,並
且補充每個象限中的殘缺位置,直到不能再劃分。利用遞歸來實現。

代碼如下:


#include<iostream>
#include<string>
#include<stdlib.h>
#include <iomanip>

using namespace std;


//遞歸實現殘缺棋盤
int tag = 0;


void  function(int tr, int tc, int dr, int dc, int size,int **target);// (tr,tc)表示該棋盤的最左上角的方格的座標。 (dr,dc)表示殘缺方格的位置座標 size表示棋盤的行列數 target是用來

//存放L型直角編碼的。 位置從(0,0)開始計算

int main()
{
 int size =16;
 int **target = new int*[size];
 //把相應的二維數組初始化 全都初始化爲0
 for (int i = 0; i < size; i++)
 {
  target[i] = new int[size];
  for (int j = 0; j < size; j++)
   target[i][j] = 0;
 }

 function(0, 0, 3, 3, size, target);

 //輸出這個數組
 for (int i = 0; i < size; i++)
 {
  for (int j = 0; j < size; j++)
  {
   cout <<setw(2)<< target[i][j] << "  ";
  }
  cout << endl;
 }

 system("pause");

 //刪除這個二維數組
 for (int i = 0; i < size; i++)
 {
  delete[] target[i];
 }
 delete[] target;
 target = 0;

 return 0;
}

void  function(int tr, int tc, int dr, int dc, int size,int **target)
{
 int s = size / 2;
 int t = ++tag;
 if (s == 0)
  return;//當size==1時不再繼續遞歸,返回上一層。

 //討論缺陷在左上角的情況
 if ((tr+s) > dr && (tc+s) > dc)
 {
  //本身所在的小棋盤保持不變
  function(tr, tc, dr, dc, s, target);
  //將右上角的棋盤的左下角的格子置爲缺陷,並且用t來標記
  target[tr + s - 1][tc + s] = t;
  function(tr, tc + s, tr + s - 1, tc + s, s, target);

  //將左下角棋盤的右上角的格子置爲缺陷,並且標記。
  target[tr + s][tc + s - 1] = t;
  function(tr + s, tc, tr + s, tr + s - 1, s, target);

  //將右下角棋盤的左上角的格子置爲缺陷,並且標記
  target[tr + s][tc + s] = t;
  function(tr + s, tc + s, tr + s, tc + s, s, target);

 }
 //討論缺陷在右上角的情況 與第一種情況相似 模仿着來寫
 //void  function(int tr, int tc, int dr, int dc, int size,int **target)
 else if ((tr+s) > dr &&(tc+s) <= dc)
 {
  target[tr + s - 1][tc + s - 1] = t;
  function(tr, tc, tr + s - 1, tr + s - 1, s, target);

  function(tr, tc + s, dr, dc, s, target);

  target[tr + s][tc + s - 1] = t;
  function(tr + s, tc, tr + s, tc + s - 1, s, target);

  target[tr + s][tc + s] = t;
  function(tr + s, tc + s, tr + s, tc + s, s, target);

 }
 //缺陷在左下角的情況
 else if ((tr+s) <= dr &&(tc+s) > dc)
 {
  target[tr+s-1][tc+s-1] = t;
  function(tr, tc, tr + s - 1, tc + s - 1, s, target);

  target[tr+s-1][tc+s] = t;
  function(tr, tc + s, tr + s - 1, tc + s, s, target);

  function(tr + s, tc, dr, dc, s, target);

  target[tr+s][tc+s] = t;
  function(tr + s, tc + s, tr + s, tc + s, s, target);
 }

 //缺陷在右下角的時候
 else 
 {
  target[tr + s - 1][tc + s - 1] = t;
  function(tr, tc, tr + s - 1, tc + s - 1, s, target);

  target[tr + s - 1][tc + s] = t;
  function(tr, tc + s, tr + s - 1, tc + s, s, target);

  target[tr + s][tc + s - 1] = t;
  function(tr + s, tc, tr + s, tc + s - 1, s, target);

  function(tr + s, tc + s, dr, dc, s, target);
 }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章