P2102 地砖铺设(dfs&贪心)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2102 地砖铺设(dfs&贪心)相关的知识,希望对你有一定的参考价值。
P2102 地砖铺设(dfs&贪心)
枚举每个点作为正方形左上角进行扩展,只需对左边界和上边界进行判断即可,然后正方形填充。因为要求最小,所以每次就特判右上角的点是否能更小,如果不行就break,否则就继续扩展。
参考代码
#include<bits/stdc++.h>
using namespace std;
char a[502][502];
int n,m,x,y;
bool same(char k,int x,int y) //判断(x,y)是否可以放入k
if (x>n||y>m) return false; //判断有没有越界
if (a[x-1][y]==k&&a[x-1][y]) return false;
if (a[x+1][y]==k&&a[x+1][y]) return false;
if (a[x][y-1]==k&&a[x][y-1]) return false;
if (a[x][y+1]==k&&a[x][y+1]) return false; //判断有没有与四周相同的
return true;
int pd(char k,int x1,int y1) //x1,y1表示扩展正方形的左上角坐标
x=x1;
y=y1; //x,y表示无法扩展到的行标和列标
int flag=0; //flag表示扩展是否成功
for (int i=1;i<=n;i++)
if (!a[x][y1]&&!a[x1][y]&&same(k,x,y1)&&same(k,x1,y))
//判断当前位置有没有被放过并且有没有与周围相同
char min1=0;
for (char ch='A';ch<k;ch++) //判断右侧位置能否更小
if (same(ch,x1,y))
min1=ch;
break;
if (min1) break; //如果发现右侧可以放更小的,就退出扩展
flag=1;
x++;y++; //往下扩展
else break;
for (int i=x1;i<x;i++) //因为x,y表示无法扩展,所以取小于号
for (int j=y1;j<y;j++) a[i][j]=k; //赋值,扩展
return flag;
int main()
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (!a[i][j])
for (char k='A';k<='Z';k++) //从小到大枚举当前位置可以放的最小值
int x=pd(k,i,j);
if (x) break; //如果成功放入,说明当前位置已经放入了最优值,退出
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
printf("%c",a[i][j]);
printf("\\n");
//愉快输出
return 0;
以上是关于P2102 地砖铺设(dfs&贪心)的主要内容,如果未能解决你的问题,请参考以下文章