题目大意:
Smart最近在装修新房子,然而房子的装修,却成为了一件难事……
Smart家的地板可以看成有n×m个格子的矩形。现在他需要用一些颜色的瓷砖来铺满这个房间,所有的瓷砖都是1×1的,每一种不同瓷砖的颜色分别用大写字母A, B, C, D, E等表示。
Smart是一个有强迫症的人,他要求铺设后的地板连成片(一块地板只与上、下、左、右四个方向相连)的颜色相同的区域必须是正方形,正方形边长不限,而且还希望按照从上到下,从左到右的顺序他房子地板颜色的字典序最小(即把n行,每行m个表示颜色的大写字母连成一个字符串后字典序最小)。
当房子为2×4时,那么他的地板应该铺设成这样:
如果铺设成下面这种情况,字典序就不是最小的。
解题思路:
还是一系列骚操作
判断能填的字典序最小的字母
一开始肯定点一个方形的”A“
然后判断~接着填,填满为止;
#include <cstdio>
#include <algorithm>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
char c[101][101],n,m,ans,sum;
int ask(int x,int y)//判断最小能填字母
{
r(i,0,5)
if(c[x-1][y]!=i+65&&c[x+1][y]!=i+65&&c[x][y+1]!=i+65&&c[x][y-1]!=i+65)
return i;
//因为只有"A","B","C","D","E",SO循环0到5就ok了
//("F"也算进去以防万一,但事实证明这并没有什么卵用)
}
bool check(int x,int y,int L,int t)//判断最小能填字母
{
int d=ask(x,y+L);
return !c[x][L+y]&&!c[L+x][y]&&t+65!=c[x+L][y-1]&&t+65!=c[x-1][y+L]&&t<=d;
}
bool IsOk(int i,int j,int L,int t)
{
return (!c[i][j+L] && !c[i+L][j]
&& t+'A'!=c[i+L][j-1] && t+'A'!=c[i-1][j+L]
&& t<=ask(i,j+L));
}
void fill(int i,int j)//填字母~
{
int l,t,x,y;
if (c[i][j]) return;
t=ask(i,j);c[i][j]='A'+t;
for (l=1;l<=min(n-i,m-j)&&IsOk(i,j,l,t);l++)
c[i][j+l]='A'+t;
r(x,i,i+l-1)
r(y,j,j+l-1)
c[x][y]='A'+t;
}
int main()
{
freopen("floor.in","r",stdin);
freopen("floor.out","w",stdout);
scanf("%d%d",&n,&m);
if (n>m)//先填一个方形的"A"
{
r(i,1,m)
r(j,1,m)
c[i][j]='A';
}else r(i,1,n)
r(j,1,n)
c[i][j]='A';
r(i,1,n)
r(j,1,m)
if (!c[i][j])//一遍一遍填
fill(i,j);
r(i,1,n)
puts(c[i]+1);//输出
return 0;
}