棋盘覆盖之分治加递归

问题

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

当初自己听了老师说的好久还是不太懂,自己就慢慢琢磨,下面仅仅代表自己的想法
在这里插入图片描述
分治与递归: 将一个大的正方形分成4个小正方形,分别为左上角,右上角,左下角,右下角,继续递归分成仅有一个格子的正方形,这里递归结束条件是正方形格子为1,而不是为1时继续递归下去,在这过程中对格子进行处理,也就是覆盖,如果特殊方格在这正方形中则继续递归,如果不在则将对比参照的正方形的对角(左下角的对角是右上角)进行覆盖,构造特殊方格,如此继续下去。
在这里插入图片描述
if条件里判断是否在左/右-上/下角正方形中的方法 : 每次按照将小块的正方形的最左上角方格作为元格子,而if里面的chek特殊方格位置不变,改变元格子的位置到小正方形的元格子进行递归
例如:(x1,y1是题目的特殊格子,x,y是元格子(每个区域的正方形的第一个格子为元格子))

 if(x1>=x+s&&y1<y+s)//左下角
    {
        chek(x+s,y,x1,y1,s);

    }
    else{
        a[x+s][y+s-1]=t;
        chek(x+s,y,x+s,y+s-1,s);
    }

当比较特殊格子是否在左下角时,以左下角黄色格子中为参照格子,元格子加上S要在黄色范围内,以便确定是否是x+s,或者x+s-1,可以把S看成是一个数如2进行计算理解
a数组 是将左下角的红色格子进行覆盖,所以是a[x+s] [y+s-1]
在这里插入图片描述
else里面的chek 参数是将黄色正方形的第一个格子作为元格子,将上一行代码覆盖的格子作为特殊格子进行填写,而s照常
如此进行下去

完整代码

#include<bits/stdc++.h>

using namespace std;
const int N=1005;
int a[N][N];
int titl=1;

void chek(int x,int y,int x1,int y1,int s2)
{
    if(s2==1)
        return;
        int s=s2/2;
    int t=titl++;
    if(x1<x+s&&y1<y+s)//左上角
        chek(x,y,x1,y1,s);//如果在此正方形内则继续递归
    else{//如果不在此正方形内则覆盖构造一个特殊方格,构造左上角的对角为特殊方格
        a[x+s-1][y+s-1]=t;//覆盖构造特殊格子
        chek(x,y,x+s-1,y+s-1,s);
    }
    if(x1>=x+s&&y1<y+s)//左下角
    {
        chek(x+s,y,x1,y1,s);

    }
    else{
        a[x+s][y+s-1]=t;
        chek(x+s,y,x+s,y+s-1,s);
    }
    if(x1<x+s&&y1>=y+s){//右上角
        chek(x,y+s,x1,y1,s);
    }else{
        a[x+s-1][y+s]=t;
        chek(x,y+s,x+s-1,y+s,s);
    }

    if(x1>=x+s&&y1>=y+s)//右下角
        chek(x+s,y+s,x1,y1,s);
    else{
        a[x+s][y+s]=t;
        chek(x+s,y+s,x+s,y+s,s);
    }
}
int main(){
	int k;
	while(cin>>k)
	{
	    int dx,dy;
        titl=1;
        for(int i=0;i<k;i++){
            for(int j=0;j<k;j++){
                    scanf("%d",&a[i][j]);
                if(a[i][j]==-1)
                    {
                        dx=i;
                        dy=j;
                    }
            }
        }
        chek(0,0,dx,dy,k);
        for(int i=0;i<k;i++){
            for(int j=0;j<k;j++){
                   printf("%d ",a[i][j]);

            }
            printf("\n");
        }

	   
	}
	return 0;
}
发布了33 篇原创文章 · 获赞 2 · 访问量 1632
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览