铺设地板

题目大意:

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值