洛谷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;
}

 

posted @ 2018-09-26 00:05  Hadesa  阅读(117)  评论(0)    收藏  举报