洛谷P1387 最大正方形
一道玄学题目,做完后才发现标签居然是dp,
但是其实暴力剪枝可以过。
说说暴力思路
枚举每一个点,如果它的值为0,很显然不可能构成正方形,直接剪掉
然后以边长为循环变量从1枚举到最大可能性,遍历正方形中的每一个点,如果发现有0直接停止这个点循环(因为哪怕是更大的正方形也会将这个点包进去,不可能满足题目需求)
最后玄学剪枝,即如果剩下的行数比现在的最大正方形的边长来得小,无论如何都不可能再构成一个最大正方形,直接输出答案
还有一个坑点,就是边长指的是有几个数而不是数之间有多少间隔
附ac代码
#include<bits/stdc++.h> using namespace std; const int Maxn=110; int square[Maxn][Maxn]; int n,m,d,maxd=0; bool have_0=false; int max(int a,int b){return a>b?a:b;} int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&square[i][j]); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ if(square[i][j]==0) continue; for(d=1;d<=min(m-j,n-i);d++){ for(int z=i;z<=i+d;z++){ for(int k=j;k<=j+d;k++) if(square[z][k]==0){ have_0=true; break; } if(have_0==true) break; } if(have_0==false) maxd=max(d,maxd); else{have_0=false; break;} } if(maxd>=n-i) break; } printf("%d",maxd+1); return 0; }

浙公网安备 33010602011771号