欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

分治5残缺的棋盘

程序员文章站 2023-12-24 12:21:15
...

可以把他平均分成四份(因为棋盘本身就是4的倍数,而且残缺部分和其他的方块刚好构成四个,所以可以将棋盘分成4的倍数平均分成四份,没分都是4的倍数)
分为左上,左下,右上,右下
然后看残缺部分在哪里把没残缺的部分填上方格,让每个部分都有被覆盖的部分或者方格,方便递归
然后递归的看每个小部分
当只有4个方格的时候要么有坏掉的部分,要么就是有被填上东西了,然后就可以填方格。

分治5残缺的棋盘
分治5残缺的棋盘

/*残缺的棋盘*/
#include<iostream>
#include<string.h>
using namespace std ;
int n,x,y;
int a[100][100];
void solution( int lx,int ly,int rx,int ry);
int main(void)
{
	//输入棋盘大小和坏点位置

	//1代表在右下角 2 代表在左下角 3 代表在右上角 4代表在左上角
	cin>>n>>x>>y;
	//构建二位坐标表示棋盘
	
	memset(a,0,sizeof(a));
	a[x][y]=7;//将有问题的位置设置为7
	//处理棋盘:
	solution(1,1,n,n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
 			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0; 
} 

void solution( int lx,int ly,int rx,int ry)//左上,右下坐标 
{
	//找到不能放的位置:
	int p=0,q=0; 
	for(int i=lx;i<=rx;i++)
	{
		for(int j=ly;j<=ry;j++)
		{
			if(a[i][j]!=0)
			{
				p=i;
				q=j;
				
				break;
			}
		}
		if(p)break;
	} 
	//如果就在周围 
	if(lx==p&&rx-lx==1&&ry-ly==1 )
	{
		if(ly==q)//如果左上角的坐标是坏点或者已经覆盖到的点 
		{
			//将后面的设置为4
			a[lx][ly+1]=4;
			a[lx+1][ly]=4;
			a[lx+1][ly+1]=4; 	
		}
		else if(ly+1==q )//如果右上角是坏点或者已经覆盖到的点 
		{
			a[lx][ly]=3;
			a[lx+1][ly]=3;
			a[lx+1][ly+1]=3;
		} 

	}
	else if(lx+1==p&&rx-lx==1&&ry-ly==1)
	{
		if(ly==q)//左下角 
		{
			a[lx][ly]=2;
			a[lx][ly+1]=2;
			a[lx+1][ly+1]=2;
		} 
		else if(ly+1==q)
		{
			a[lx][ly]=1;
			a[lx][ly+1]=1;
			a[lx+1][ly]=1;
		}
	}
	//如果不在周围就看大概在哪个方向:
	else
	{
		//算中间值 
		int zx,zy;
		zx=(lx+rx)/2;
		zy=(ly+ry)/2;
		if(p<zx)
		{
			if(q<zy)//左上
			{
				a[zx][zy+1]=4;
				a[zx+1][zy]=4;
				a[zx+1][zy+1]=4; 
			} 
			else if(q>zy)
			{
			a[zx][zy]=3;
			a[zx+1][zy]=3;
			a[zx+1][zy+1]=3;
			}
		}
		else 
		{
			if(zy>q)//左下角 
			{
			a[zx][zy]=2;
			a[zx][zy+1]=2;
			a[zx+1][zy+1]=2;
			} 
			else if(zy<q)
			{
			a[zx][zy]=1;
			a[zx][zy+1]=1;
			a[zx+1][zy]=1;
			}
		}
		solution(  lx,ly,zx,zy);//递归左上 
		solution(   lx,zy+1,zx,ry);//递归右上 
		solution(   zx+1,ly,rx,zy);//递归左下 
		solution(  zx+1,zy+1,rx,ry);//递归左下 
	} 
}

上一篇:

下一篇: