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

棋盘覆盖问题。有一个2k∗2k2k∗2k的方格棋盘,恰有一个方格是黑色的,其他为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。如图所示为L型牌的4种旋转方式。  

  当一个黑块位于某一角时,可以解决一个边长为2的正方形匹配。可是这样只解决了一个正方形,想解决其他正方形,需要为其他每个正方形在某一角增加一个黑块,然后该问题可以针对不同的角分别进行分治。

#include<bits/stdc++.h>
using namespace std;

int title=1;
int board[8][8];
void chessboard(int tr,int tc,int dr,int dc,int size);
int main(){
	
		printf("请输入边长\n");
	int n;
	scanf("%d",&n);
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			board[i][j] = 0;
		}
	}

	chessboard(0,0,0,0,n);

	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			printf("%4d",board[i][j]);
		}
		cout<<endl;
	}
}
	


void chessboard(int tr,int tc,int dr,int dc,int size){
	if(size==1)
	return ;
	
	int t=title++;
	int s=size/2;
	//左上棋盘 
	if(tr+s>dr && tc+s>dc){           //特殊方格 在左上角 
		chessboard(tr,tc,dr,dc,s);
		
	}
	else{
		board[tr+s-1][tc+s-1]=t;					//L型牌覆盖该位置,并为该位置标号 
		chessboard(tr,tc,tr+s-1,tc+s-1,s);         // 使左上角的子棋盘的右下角成为特殊位置
			
	}
	
	//右上棋盘 
	if(tr+s>dr && tc+s<=dc){          //特殊方格 在右上角 
			chessboard(tr,tc+s,dr,dc,s);
	}
	else{
		board[tr+s-1][tc+s]=t;                  //L型牌覆盖该位置,并为该位置标号 
		chessboard(tr,tc+s,tr+s-1,tc+s,s);       	//使右上角的棋盘的左下角成为特殊位置 
	}

	//左下棋盘 
	if(tr+s<=dr && tc+s>dc){                  //特殊方格 在左下角 
		chessboard(tr+s,tc,dr,dc,s);
	}
	else{  
		board[tr+s][tc+s-1]=t;                  //L型牌覆盖该位置,并为该位置标号 
		chessboard(tr+s,tc,tr+s,tc+s-1,s);     //使左下角的棋盘的右上角成为特殊位置  
	}
	
	//右下棋盘 
	if(tr+s<=dr && tc+s<=dc){        //特殊方格 在右下角 
		chessboard(tr+s,tc+s,dr,dc,s);
	}
	else{
		board[tr+s][tc+s]=t;                       //L型牌覆盖该位置,并为该位置标号 
		chessboard(tr+s,tc+s,tr+s,tc+s,s);         //右下角的棋盘的左上角成为特殊位置 
	}

}
发布了57 篇原创文章 · 获赞 58 · 访问量 638

猜你喜欢

转载自blog.csdn.net/weixin_43568895/article/details/103656760