【JZOJ3807】地砖铺设

来源:互联网 发布:wcl国服数据 编辑:程序博客网 时间:2024/04/28 16:54

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 110using 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");    }}
1 0