用分治策略实现棋盘覆盖问题


C++程序源代码如下:

// 棋盘覆盖.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include<iostream>

#include<fstream>

using namespace std;

int tile=1; //L型骨牌的编号(递增)

int board[100][100]; //棋盘

/*****************************************************

* 递归方式实现棋盘覆盖算法

* 输入参数:

* tr:当前棋盘左上角的行号

* tc:当前棋盘左上角的列号

* dr:当前特殊方格所在的行号

* dc:当前特殊方格所在的列号

* size:size=2^k,棋盘规格为2^k*2^k

*****************************************************/

void chessBoard ( int tr, int tc, int dr, int dc, int size )

{

    if ( size==1 ) //棋盘方格大小为1,说明递归到最里层

        return;

    int t=tile++; //每次递增1

    int s=size/2; //棋盘中间的行、列号(相等的)

    //检查特殊方块是否在左上角子棋盘中

    if ( dr<tr+s && dc<tc+s ) //在

        chessBoard ( tr, tc, dr, dc, s );

    else //不在,将该子棋盘右下角的方块视为特殊方块

    {

        board[tr+s-1][tc+s-1]=t;

        chessBoard ( tr, tc, tr+s-1, tc+s-1, s );

    }

    //检查特殊方块是否在右上角子棋盘中

    if ( dr<tr+s && dc>=tc+s ) //在

        chessBoard ( tr, tc+s, dr, dc, s );

    else //不在,将该子棋盘左下角的方块视为特殊方块

    {

        board[tr+s-1][tc+s]=t;

        chessBoard ( tr, tc+s, tr+s-1, tc+s, s );

    }

    //检查特殊方块是否在左下角子棋盘中

    if ( dr>=tr+s && dc<tc+s ) //在

        chessBoard ( tr+s, tc, dr, dc, s );

    else //不在,将该子棋盘右上角的方块视为特殊方块

    {

        board[tr+s][tc+s-1]=t;

        chessBoard ( tr+s, tc, tr+s, tc+s-1, s );

    }

    //检查特殊方块是否在右下角子棋盘中

    if ( dr>=tr+s && dc>=tc+s ) //在

        chessBoard ( tr+s, tc+s, dr, dc, s );

    else //不在,将该子棋盘左上角的方块视为特殊方块

    {

        board[tr+s][tc+s]=t;

        chessBoard ( tr+s, tc+s, tr+s, tc+s, s );

    }

}

int fuc(int i)

{

int count = 0;

while(i)

{

count += i&0x01;

i >>= 1;

}

if(count < 2)

     return 1;

else

     return 0;

}

void menu();

void input()

{

    ofstream outfile;

    outfile.open("output.txt");

    int size;

    int index_x,index_y;

flag:

    cout<<"输入棋盘的size(大小必须是2的n次幂): ";

    cin>>size;

    if(fuc(size)!=1){

        cout<<"输入错误,";

        goto flag;

    }

flag2:

    cout<<"输入特殊方格位置的行号与列号(从0开始): ";

    cin>>index_x>>index_y;

    if (index_x >= size||index_y>=size){

        cout<<"特殊方格位置超出棋盘范围,";

        goto flag2;

    }

    chessBoard ( 0,0,index_x,index_y,size );

    for ( int i=0; i<size; i++ )

    {

        for ( int j=0; j<size; j++ ){

            cout<<board[i][j]<<"\t";

        }

        cout<<endl<<endl;    

    }

    //输出到文件

    for ( int i=0; i<size; i++ )

    {

        for ( int j=0; j<size; j++ ){

            outfile<<board[i][j]<<"\t";

        }

        outfile<<endl<<endl;    

    }

    cout<<"最后一次棋盘覆盖结果已输出到output.txt中"<<endl;

    outfile.close() ;

    menu();

}

void menu()

{

    char c;

    cout<<"是否继续输入(Y/N)?";

    cin>>c;

    if( c == ‘Y‘||c == ‘y‘)

        input();

}

void main()

{

    input();

}


测试数据:

Size=8

特殊方格位置的行号:3,4

本次实验程序运行结果如下:

Output.txt:

3    3    4    4    8    8    9    9

3    2    2    4    8    7    7    9

5    2    6    6    10    10    7    11

5    5    6    1    0    10    11    11

13    13    14    1    1    18    19    19

13    12    14    14    18    18    17    19

15    12    12    16    20    17    17    21

15    15    16    16    20    20    21    21


因为采用的是C++的控制台程序,所以不能以图形方式输出,结果还不够直观。并且在控制台界面的输出方格数目不能太多,所以我将最后一次输出结果写入了output.txt文件中,这样可以使显示的方格数更多!

时间: 2024-10-25 09:35:21

用分治策略实现棋盘覆盖问题的相关文章

分治与递归-棋盘覆盖问题

在一个2^k×2^k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有4^k种情形.因而对任何k≥0,有4^k种不同的特殊棋盘.     下图–图(1)中的特殊棋盘是当k=3时16个特殊棋盘中的一个: 图(1) 题目要求在棋盘覆盖问题中,要用下图-图(2)所示的4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖. 容易忽视的地方:棋盘分割以后,坐标会发生改变,所以要

算法复习_分治算法之二分搜索、棋盘覆盖、快速排序

一.基本概念 分治法,顾名思义,即分而治之的算法,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题…… 二.基本思想及策略 设计思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 策略:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解.这种算法设计策略叫做分治法. 三

【棋盘覆盖】(简单)--分治算法

算法实验1:棋盘覆盖 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 2798  Solved: 702 [Submit][Status][Discuss] Description 在一个2k x 2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖. 口            

递归分治解决棋盘覆盖问题

package algorithm; //递归分治解决棋盘覆盖问题 public class ChessBoard { //tr棋盘左上角方格的行号 //tc棋盘左上角方格的列号 //size = 2^k棋盘规格为2^k *2^k //dr特殊方格所在的行号 //dc特殊方格所在的列号 private static int tile = 0;//L型骨牌号 public static int[][] Board = new int[100][100]; public static void ch

棋盘覆盖问题【分治】

棋盘覆盖问题 Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB Total submit users: 95, Accepted users: 36 Problem 10432 : No special judgement Problem description   在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.

分治算法----棋盘覆盖问题

问题描述 在一个2^k×2^k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖.

棋盘覆盖问题(递归分治)

       问题描述: 在一个2^k×2^k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有4^k种情形.因而对任何k≥0,有4^k种不同的特殊棋盘.     下图–图(1)中的特殊棋盘是当k=3时16个特殊棋盘中的一个: 图(1) 题目要求在棋盘覆盖问题中,要用下图-图(2)所示的4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖. 图(2) 题目包含多组测试

棋盘覆盖问题

棋盘覆盖问题       问题描述: 在一个2^k×2^k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有4^k种情形.因而对任何k≥0,有4^k种不同的特殊棋盘.     下图–图(1)中的特殊棋盘是当k=3时16个特殊棋盘中的一个: 图(1) 题目要求在棋盘覆盖问题中,要用下图-图(2)所示的4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖. 图(2) 题目

js算法:分治法-棋盘覆盖

在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其他方格不同.则称该方格为一特殊方格,称该棋盘为一特殊棋盘.显然特殊方格在棋盘上出现的位置有 4^k 种情形.因而对不论什么 k>=0 .有 4^k 种不同的特殊棋盘. 下图所看到的的特殊棋盘为 k=2 时 16 个特殊棋盘中的一个. 在棋盘覆盖问题中,要用下图中 4 中不同形态的 L 型骨牌覆盖一个给定的特殊棋牌上除特殊方格以外的全部方格,且不论什么 2 个 L 型骨牌不得重叠覆盖. 易知,在不论什么一个 2^k * 2^k 的棋