残缺棋盘 分治

在这里插入图片描述
分析:
在这种限制条件下,所需要的三格板总数为?
1)被覆盖板面积(除去残缺方格)为2k×2k-1 (k≥1) ;
2)三格板之间不能重叠;
3)三格板不能覆盖残缺方格,但必须覆盖其他所有方格。

(2k×2k-1)/3

2^k^×2^k^-1--->4^k^-1---->(3+1)^k^-1所得结果一定会被三整除

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>

using namespace std;

int amount = 0;//用的块数 
int Board[100][100];//棋盘记录 

void Cover(int tr,int tc,int dr,int dc,int size)
{
	int s;
	int t;
	if(size==1) return;
	s=size/2;//拆分成四份小格
	t=++amount; 
	//第一种情况,残缺方块在左上角
	if(dr < tr + s && dc < tc +s)
	{
		Cover(tr,tc,dr,dc,s);//进入残缺方格所在小块的进一步划分 
	}else{
		Board[tr+s-1][tc+s-1] = t;
		Cover(tr,tc,tr+s-1,tc+s-1,s);
	}
	//第二种情况,残缺方块在右上角
	if(dr < tr + s && dc >= tc +s)
	{
		Cover(tr,tc+s,dr,dc,s);//进入残缺方格所在小块的进一步划分 
	}else{
		Board[tr+s-1][tc+s]=t;
		Cover(tr,tc+s,tr+s-1,tc+s,s);
	}
	//第三种情况,残缺方块在左下角
	if(dr >= tr + s && dc < tc +s)
	{
		Cover(tr+s,tc,dr,dc,s);//进入残缺方格所在小块的进一步划分 
	}else{
		Board[tr+s][tc+s-1]=t;
		Cover(tr+s,tc,tr+s-1,tc+s,s);
	}
	//第四种情况,残缺方块在右下角
	if(dr >= tr + s && dc >= tc +s)
	{
		Cover(tr+s,tc+s,dr,dc,s);//进入残缺方格所在小块的进一步划分 
	}else{
		Board[tr+s][tc+s]=t;
		Cover(tr+s,tc+s,tr+s,tc+s,s);
	}
}


int main()
{
    int size,r,c,row,col;//棋盘大小size*size  棋盘左上角顶格的坐标(r,c) 残缺位置(row,col) 
    printf("请输入棋盘大小(2的整数幂)size: "); 
    scanf("%d",&size);
    printf("请输入残缺方块的位置:"); 
    scanf("%d%d",&row,&col);
    Cover(0,0,row,col,size);
    for (r = 0; r < size; r++)
    {
        for (c = 0; c < size; c++)
        {
            printf("%2d ",Board[r][c]);
        }
        printf("\n");
    }

    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44916213/article/details/112298244