分治--残缺棋盘

题目:TheBeet有一个块大小为(2 N*2 N)的棋盘。这个棋盘是由一个个格子组成的。很不幸的,在一个月黑风高的晚上,它被摔坏了。不幸中的万幸,它只被摔坏了一个格子(此格子可以在棋盘的任意位置)。

 

 

但是这个棋盘再也不能用来下棋了,于是TheBeet想把这个棋盘切成如以下的几种小块。但是TheBeet不想浪费任何一个格子,您能帮助TheBeet么?

 

分析:采用分治法,可以把问题分解为4个子问题。每次把棋盘从中间切开,分成相同大小的4部分。有缺点那部分不用再设置缺点,没有缺点的其他3部分设置靠近切开前棋盘中心的那一点设置为缺点。不断迭代……
#include<iostream>
#include<cstdlib>
/*对棋盘平均四等分,如果残缺格不在对应的等分中则标记等分块以交点为顶点的格子组成新的残缺格*/
using namespace std;
#define max 1025
int board[max][max] = { 0 };
int bs = 1, flag = 1;
void show()
{
	for (int i = 1; i <= bs; i++)
	{
		for (int j = 1; j <= bs; j++)
			printf("%d ", board[i][j]);
		printf("\n");
	}
	printf("\n");
}
void chessboard(int br, int bc, int m, int n, int size)
{
	if (size <= 1) return;
	else size = size / 2;
	int term = flag++;
	if (m<br + size&&n<bc + size)//左上角
		chessboard(br, bc, m, n, size);
	else
	{
		board[br + size - 1][bc + size - 1] = term;
		//cout<< br + size - 1 << " " << bc + size - 1 << " " << term << endl;
		chessboard(br, bc, br + size - 1, bc + size - 1, size);
	}
	if (m<br + size&&n >= bc + size)//右上角
		chessboard(br, bc + size, m, n, size);
	else
	{
		board[br + size - 1][bc + size] = term;
		//cout << br + size - 1 << " " << bc + size << " " << term << endl;
		chessboard(br, bc + size, br + size - 1, bc + size, size);
	}
	if (m >= br + size&&n<bc + size)//左下角
		chessboard(br + size, bc, m, n, size);
	else
	{
		board[br + size][bc + size - 1] = term;
		//cout << br + size << " " << bc + size - 1 << " " << term << endl;
		chessboard(br + size, bc, br + size, bc + size - 1, size);
	}
	if (m >= br + size&&n >= bc + size)//右下角
		chessboard(br + size, bc + size, m, n, size);
	else
	{
		board[br + size][bc + size] = term;
		//cout << br + size << " " << bc + size << " " << term << endl;
		chessboard(br + size, bc + size, br + size, bc + size, size);
	}
}
int main()
{
	int number, m, n;
	scanf("%d", &number);
	scanf("%d%d", &m, &n);
	//number = 2;
	//m = 1;
	//n = 4;
	for (int i = 1; i <= number; i++)
		bs *= 2;
	chessboard(1, 1, m, n, bs);
	show();
	return 0;
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值