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&贪心)的主要内容,如果未能解决你的问题,请参考以下文章

铺地砖(状压DP)

[题解] luogu P1514 引水入城 DFS + 贪心覆盖区间

BZOJ 1248--游乐园(DFS&贪心)

42模拟测试题归并排序树规贪心

题解 CF1359B New Theatre Square

题解 CF1359B New Theatre Square