1. 程式人生 > >分治法求棋盤覆蓋問題

分治法求棋盤覆蓋問題

問題:

在一個2^k×2^k (k≥0)個方格組成的棋盤中,恰有一個方格與其他方格不同,稱該方格為特殊方格。顯然,特殊方格在棋盤中可能出現的位置有4^k種,因而有4^k種不同的棋盤,圖4.10(a)所示是k=2時16種棋盤中的一個。棋盤覆蓋問題(chess cover problem)要求用圖4.10(b)所示的4種不同形狀的L型骨牌覆蓋給定棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。

C++程式碼實現:

/*a,b代表左上角方格的行,列座標,x,y代表特殊方格的行列座標
0代表特殊方格的位置,相同的數字代表L型骨牌的位置 
*/ 
#include<iostream>
using namespace std;
int tile=1;                   
int Board[100][100];  
void ChessBoard(int a,int b,int x,int y,int size)
{
    if(size==1) return;
    int t=tile++,s=size/2;
    //printf("%d\n",t);
    if(x<a+s && y<b+s)//在左上角區域內
    ChessBoard(a,b,x,y,s);
    else//不在左上角區域內
    {
        Board[a+s-1][b+s-1]=t;//用t號(用一個數字表示)L型骨牌覆蓋右下角
        ChessBoard(a,b,a+s-1,b+s-1,s);///覆蓋剩餘方格
    }
    if(x<a+s && y>=b+s)//在右上角區域內
        ChessBoard(a,b+s,x,y,s);
    else//不在右上角的區域內
    {
        Board[a+s-1][b+s]=t;
        ChessBoard(a,b+s,a+s-1,b+s,s);
    }
    if(x>=a+s && y<b+s)//左下角區域 
        ChessBoard(a+s,b,x,y,s);
    else
    {
        Board[a+s][b+s-1]=t;
        ChessBoard(a+s,b,a+s,b+s-1,s);
    }
    if(x>=a+s && y>=b+s)//右下角區域 
        ChessBoard(a+s,b+s,x,y,s);
    else
    {
        Board[a+s][b+s]=t;
        ChessBoard(a+s,b+s,a+s,b+s,s);
    }
}
int main()
{
    int size;
     cout<<"輸入棋盤的size(大小必須是2的n次冪): ";
     cin>>size;
     int x,y;
     cout<<"輸入特殊方格位置的座標: ";
     cin>>x>>y;
     ChessBoard (0,0,x-1,y-1,size );
     for ( int i=0; i<size; i++ )
     {
         for ( int j=0; j<size; j++ )
             cout<<Board[i][j]<<'\t';
         cout<<endl;
     }
}

相關推薦

治法棋盤覆蓋問題

問題: 在一個2^k×2^k (k≥0)個方格組成的棋盤中,恰有一個方格與其他方格不同,稱該方格為特殊方格。顯然,特殊方格在棋盤中可能出現的位置有4^k種,因而有4^k種不同的棋盤,圖4.10(a)

治法x的y次方

echo lan IT aik 關於 targe div item pre 關於分治法 <?php function powerdiv($x, $n) { if($x==1) { return 1; } elseif ($x==0

治法最大最小

即使 OS clas 判斷 如果 nbsp pos pre printf 1 #include<stdio.h> 2 /* 分治法計算最大值和最小值的算法程序,遞歸實現 */ 3 void maxmin2(int d[], int left, int r

治法平面最近點對

題意 Here 思考 之前考分治的時候有一道題,要用到 \(O(nlogn)\) 求平面最近點對,然而當時我不會……現在寫篇部落格回顧一下。 平面上 \(n\) 個點,讓我們求最近點對,最樸素的想法是列舉,複雜度 \(O(n^2)\) 這樣是顯然過不了 \(1e5\) 的資料的,同時我們也發現對於一

治法陣列中最大元素

原創 在陣列A[n]中,設m是其中最大元素,則m=max(A[0],max( A[1]……A[n-1]); 同理 max( A[1]……A[n-1] ) = max ( A[1] , max( A[2]……A[n-1] ); 設函式findMax( int index ) 是尋找陣列中最大

對於治法大整數相乘程式碼以及思路

分治演算法步驟: 1. 分解,將要解決的問題劃分為若干個規模較小的同類問題 2. 求解,當子問題劃分的足夠小時,用較簡單的方法解決 3. 合併,按原問題的要求,將子問題的解逐層合併構成原始問題的解 對於大整數相乘 需要如下幾步: 如 1234 5678 首先進行分解:

治法最近對問題

首先感謝博主https://www.cnblogs.com/zuoyou151/p/9059903.html,讓我收穫很多,今天感覺很困,狀態不佳,解析與講解會改天補上,註明:我這裡採用遞迴時是左閉右開區間,而博主採用的左閉右閉。 還有感謝“NX”童鞋為我調好VS2017,之前因為環境問題一

治法二維凸包問題java

https://blog.csdn.net/bone_ace/article/details/46239187 見解法2。 有一點需要說明的是,如果有多個到直線p1 pn的距離都最大的點,找pmax使的∠pmax p1 pn最大 下面為java程式碼 package fd; impo

[演算法入門經典] 8.1.3 治法 最大連續和

int maxsum(int *A,int x,int y) //返回陣列在左比右開區間[x,y)中的最大連續和 { int i, m, v, L, R, max; if(y-x==1) return A[x]; //只有一個元素,直接返回 m=x+(

治法兩個長度相同都按升序排列陣列的中位數

#include <iostream> using namespace std; void Mid(int a[],int aleft,int aright,int b[],int bleft,int bright) { double mid;

POJ 2299 治法數列逆序對(歸併排序)

Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 50482 Accepted: 18516 Description In this proble

演算法設計--蠻力法&&治法最近對問題(C++實現)

最近對問題? 設p1=(x1,y1), p2(x2,y2), ....,pn=(xn,yn)是平面上n個點構成的集合S,最近對問題就是找出集合S中距離最近的點對。 兩種演算法思想: 1. 蠻力法:顧名思義,利用正常的思維,使用強硬的方式求解出結果。 2. 分治法:分治,分而

治法整數相乘

3824 *4369 =(38*10^2+24)*(43*10^2+69) =(38*43)*10^2+(38*69+43*24)*10+24*69 這樣將相乘的數分成小的數相乘 #include<iostream> #include<algorith

治法最大最小元

#include<iostream> using namespace std; int fmax(int a, int b) { return (a > b) ? a : b; }

治法 逆序對數 的個數 時間複雜度為O(n*logn)

思路: 分治法 歸併排序的過程中,有一步是從左右兩個陣列中,每次都取出小的那個元素放到tmp[]陣列中 右邊的陣列其實就是原陣列中位於右側的元素。當不取左側的元素而取右側的元素時,說明左側剩下的元素均

蠻力法和治法 最近對問題——Java 實現

public class ClosestPair2{ public static void main(String[] args) {  /**   *輸入需要比較的點的對數存在變數n中   */  Scanner in=new Scanner(System.in);  System.out.println(

治法最大子段和

#include<iostream> using namespace std; int MaxSubSum(int a[],int left,int right){ int sum=

治法——逆序數**

iostream sort delet [] void http 思考 delete trait // test.cpp: 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include<iostream> #inclu

治法-棋盤覆蓋問題

問題描述: 在一個2k×2k 個方格組成的棋盤中,有一個方格與其它不同,稱該方格為特殊方格,且稱該棋盤為一特殊棋盤。             k=2時的一種棋盤 要求用下圖所示的4種L形態骨牌覆蓋給定的特殊棋盤。

演算法07:棋盤覆蓋——治法Part3

(3)棋盤覆蓋 在一個2k×2k 個方格組成的棋盤中,恰有一個方格與其它方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用圖示的4種不同形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。 分治法的思想