分治5残缺的棋盘
程序员文章站
2023-12-24 12:21:15
...
可以把他平均分成四份(因为棋盘本身就是4的倍数,而且残缺部分和其他的方块刚好构成四个,所以可以将棋盘分成4的倍数平均分成四份,没分都是4的倍数)
分为左上,左下,右上,右下
然后看残缺部分在哪里把没残缺的部分填上方格,让每个部分都有被覆盖的部分或者方格,方便递归
然后递归的看每个小部分
当只有4个方格的时候要么有坏掉的部分,要么就是有被填上东西了,然后就可以填方格。
/*残缺的棋盘*/
#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);//递归左下
}
}