分治法实现棋盘覆盖

来源:互联网 发布:剑灵天族女身体数据图 编辑:程序博客网 时间:2024/05/18 22:10

问题描述:用图所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。


思路:应用分治法
分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题。k>0 时,可将2^k×2^k的棋盘划分为4个2^(k-1)×2^(k-1)的子棋盘,如图4.11(a)所示。这样划分后,由于原棋盘只有一个特殊方格,所 以,这4个子棋盘中只有一个子棋盘包含该特殊方格,其余3个子棋盘中没有特殊方格。为了将这3个没有特殊方格的子棋盘转化为特殊棋盘,以便采用递归方法求 解,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种划分策略, 直至将棋盘分割为1×1的子棋盘。


递归:在一个算法调用另一个算法时,系统需要建立递归调用工作栈,并在运行被调用算法之前先完成3件事:

(1)将所有的实参参数,返回地址等信息传递给被调算法保存。 

(2)为被调算法的局部变量分配存储区。

(3)将控制转移到被调函数的入口。

从被调算法返回调用算法之前,系统也要完成三项工作:

(1)保存被调算法的计算结果。 

(2)释放被调算法的数据区。 

(3)依照被调算法保存的返回地址将控制转移到调用算法。

分治法:将规模为n的问题分成k个规模为n/m的子问题去解


public void FromJava() {    int N = 8;    int specialRow = 0;    int specialCol = 1;    ChessBoradProblem boradProblem = new ChessBoradProblem(specialRow, specialCol, N);    boradProblem.printBoard(specialRow, specialCol, N);}public class ChessBoradProblem {    private int[][] board;//棋盘    private int specialRow;//特殊点的行下标    private int specialCol;//特殊点的列下标    private int size;    private int type = 0;    public ChessBoradProblem(int specialRow, int specialCol, int size) {        super();        this.specialRow = specialRow;        this.specialCol = specialCol;        this.size = size;        board = new int[size][size];    }    private void ChessBoard(int specialRow,int specialCol,int leftRow,int leftCol,int size){        if(size == 1){            return;        }        int subSize = size/2;        type = type%4 + 1;        int n = type;        if (specialRow<leftRow+subSize&&specialCol<leftCol+subSize){            ChessBoard (specialRow,specialCol,leftRow,leftCol,subSize);        }else {            board[leftRow+subSize-1][leftCol+subSize-1]=n;            ChessBoard (leftRow+subSize-1,leftCol+subSize-1,leftRow,leftCol,subSize);        }        if (specialRow<leftRow+subSize&&specialCol>=leftCol+subSize){            ChessBoard (specialRow,specialCol,leftRow,leftCol+subSize,subSize);        }else {            board[leftRow+subSize-1][leftCol+subSize]=n;            ChessBoard (leftRow+subSize-1,leftCol+subSize,leftRow,leftCol+subSize,subSize);        }        if (specialRow>=leftRow+subSize&&specialCol<leftCol+subSize){            ChessBoard (specialRow,specialCol,leftRow+subSize,leftCol,subSize);        }else {            board[leftRow+subSize][leftCol+subSize-1]=n;            ChessBoard (leftRow+subSize,leftCol+subSize-1,leftRow+subSize,leftCol,subSize);        }        if (specialRow>=leftRow+subSize&&specialCol>=leftCol+subSize){            ChessBoard (specialRow,specialCol,leftRow+subSize,leftCol+subSize,subSize);        }else {            board[leftRow+subSize][leftCol+subSize]=n;            ChessBoard (leftRow+subSize,leftCol+subSize,leftRow+subSize,leftCol+subSize,subSize);        }    }    public void printBoard(int specialRow,int specialCol,int size){        ChessBoard(specialRow, specialCol, 0, 0, size);        printResult();    }    private void printResult() {        for(int i = 0;i<size;i++){            for(int j = 0;j<size;j++){                System.out.print(board[i][j]+" ");            }            System.out.println();        }    }}

原创粉丝点击