• 棋盘覆盖问题(看完这个就好)


    棋盘覆盖(C语言)

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

    下面我来说说我的理解吧:

    首先,我们按照最小的模式,也就是 k=0 的时候,此时只有一个特殊方格没有三角方格需要放置,当然这种情况还是比较少的。
    接下来,就是 k=1 的时候,也就是有四个方格,无论特殊方格的位置在哪,我们都可以找到一个直角方格放置。

    接下来,就是 k 不断地递增,利用分治的思想,可以把大方格划分成小方格,划分到最后就剩下最后一个包含有特殊方格的四方格,这个时候,我们的直角方格该以哪种形式存在呢?对吧,面临的四边其实都是可以放置直角方格的。
    这个时候利用分治的思想,也就是说把原有的大方个,划分成四个相对小一个阶级的方格

    到最后就回到了递归的出口,也就是说,特殊方格分别在四方格的四个角上的情况。

    #include<stdio.h>
    #define n 8     //n为2^k
    int tr,tc;     //子棋盘的左上角第一个方格的横纵坐标
    int dr,dc;     //特殊方格的横纵坐标
    int size;
    int board[n][n];
    int tile=1;   //骨牌序号从1开始
    void input()
    {
        printf("输出棋盘长度:%d
    ",n);
        printf("请输入特殊棋盘的位置dr,dc:");
        scanf("%d,%d",&dr,&dc);
        board[dr][dc]=0;
    }
    void chess(int tr,int tc,int dr,int dc,int size)
    {
        if(size==1)
            return;
        int t=tile++;
        int s=size/2;
        if(dr<tr+s && dc<tc+s)     //特殊方格在左上方
            chess(tr,tc,dr,dc,s);
        else
        {
            board[tr+s-1][tc+s-1]=t;
            chess(tr,tc,tr+s-1,tc+s-1,s);
        }
        if(dr<tr+s && dc>=tc+s)     //特殊方格在右上方
            chess(tr,tc+s,dr,dc,s);
        else
        {
            board[tr+s-1][tc+s]=t;
            chess(tr,tc+s,tr+s-1,tc+s,s);
        }
        if(dr>=tr+s && dc<tc+s)     //特殊方格在左下方
            chess(tr+s,tc,dr,dc,s);
        else
        {
            board[tr+s][tc+s-1]=t;
            chess(tr+s,tc,tr+s,tc+s-1,s);
        }
        if(dr>=tr+s && dc>=tc+s)     //特殊方格在右下方
            chess(tr+s,tc+s,dr,dc,s);
        else
        {
            board[tr+s][tc+s]=t;
            chess(tr+s,tc+s,tr+s,tc+s,s);
        }
    }
    void display()    //输出二维数组
    {
        int i,j;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                printf("%4d ",board[i][j]);
            }
            printf("
    
    ");
        }
    }
    void main()
    {
        input();
        chess(0,0,dr,dc,n);
        display();
    }
    

    代码应该可以看明白
    在这里插入图片描述

  • 相关阅读:
    C语言左移和右移
    mmap详谈
    eclipse插件自动生成类图
    async 和 defer 的区别
    SVN里恢复到某一天的版本操作
    解决跨域的jsonp+Java实例
    HTTP请求行、请求头、请求体等
    ajax在什么情况下会走success和error
    记阅读POST与GET的区别
    记一些快捷键
  • 原文地址:https://www.cnblogs.com/Indomite/p/14195238.html
Copyright © 2020-2023  润新知