【JZOJ3807】地砖铺设

Description

在游戏厅大赚了一笔的Randy 终于赢到了他想要的家具。乘此机会,他想把自己的房间好好整理一下。
在百货公司,可以买到各种各样正方形的地砖,为了美观起见,Randy 不希望同样颜色的正方形地
砖相邻。所以他找到了Tio 来帮忙解决这件事情。
Tio 很快解决了这个任务。然而,出于某种强迫症,她希望在地上按照长宽划分成网格后,逐行逐
列每一块的颜色组成的序列的字典序最小。她希望你帮忙验证一下她的方案。

Solution

从左到右从上到下填,对于每个格子,先判断它可以填的最小的字母是什么,如果这个字母和前面的相等,那么就以前面那个为左上角扩展一个最大的正方形。

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 110
using namespace std;
int a[N][N];
bool bz[N][N];
void print(int x1,int y1,int x2,int y2,int c)
{
    fo(i,x1,x2)
    fo(j,y1,y2) a[i][j]=c,bz[i][j]=true;
}
int find(int x,int y)
{
    fo(i,0,25)
    if(i!=a[x-1][y] && i!=a[x+1][y] && i!=a[x][y+1]) return i;
}
int find1(int x,int y)
{
    fo(i,0,25)
    if(i!=a[x-1][y] && i!=a[x][y-1] && i!=a[x+1][y] && i!=a[x][y+1]) return i;
}
int n,m;
int qq;
void dfs(int x,int y)
{
    if(x>n) return;
    if(x==4 && y==2)
    {
        qq++;
        qq--;
    }
    if(a[x][y]!=-1)
    {
        if(y<m) dfs(x,y+1);
        else dfs(x+1,1);
        return;
    }
    int co=find1(x,y),cc=find(x,y);
    if(!bz[x][y-1] && cc==a[x][y-1])
    {
        int p=x,q=y-1;
        while(a[p+1][q+1]==-1 && p<n && q<m) p++,q++;
        print(x,y-1,p,q,cc);
        if(p==x) a[x][y]=co;
    }
    else a[x][y]=co;
    if(y<=m) dfs(x,y+1);
    else dfs(x+1,1);
}
int main()
{
    scanf("%d %d",&n,&m);
    memset(a,-1,sizeof(a));
    dfs(1,1);
    fo(i,1,n)
    {
        fo(j,1,m)
        printf("%c",char(a[i][j]+'A'));
        printf("\n");
    }
}
posted @ 2017-01-09 19:05  sadstone  阅读(46)  评论(0编辑  收藏  举报