题解
又是做 NOI.AC 的题,题目质量还行,但估计不是原创的
洛谷上面第一题找得到原题,只是改了题面而已
第一题——地砖设计
【题目描述】
- 要求用正方形边长的颜色填满 m ∗ n m*n m∗n的地图,相同颜色不能相邻,要求输出地图的字典序最小。
- 颜色用ABCD等填满
- 这个我以为是无脑贪心,结果有点小难度,贪心策略不正确。
- 正确的贪心策略是从左往右一个个节点枚举,在枚举到当前节点的时候向右下进行拓展,然后再看能不能用字典序更小的合法解进行替换,从而使得字典序变得更小。
- 然后不知道怎么证明。但是颜色是超不过D的。
#include <bits/stdc++.h>
using namespace std;
const int N=110;
int n,m;
int mp[N][N];
char ch[5]={
'A','B','C','D','E'};
bool check(int color,int i,int j){
if(mp[i-1][j]==color) return false;
if(mp[i][j+1]==color) return false;
if(mp[i+1][j]==color) return false;
if(mp[i][j-1]==color) return false;
return true;
}
bool work(int x,int y,int color){
bool flag=false;
int tx=x,ty=y;
for(int i=1;i<=n;i++){
if(tx>n||ty>m) break;
if(mp[x][ty]==-1&&mp[tx][y]==-1&&check(color,x,ty)&&check(color,tx,y)){
int minn=0;
for(int j=1;j<color;j++){
if(check(j,x,ty)){
minn=j;
break;
}
}
if(minn) break;
flag=true;
tx++,ty++;
}else break;
}
for(int i=x;i<tx;i++)
for(int j=y;j<ty;j++)
mp[i][j]=color;
return flag;
}
int main(){
scanf("%d%d",&n,&m);
memset(mp,-1,sizeof(mp));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)