P1387 最大正方形

---------------------------------------------------

这道题还是很有趣的

---------------------------------------------------

大佬们都用了搜索,DP等做法,而本蒟蒻刚刚学了二维前缀和,所以就用了二维前缀和来做这道题

什么是二维前缀和?

(你一定知道什么是一维前缀和)

二维前缀和就是一维前缀和多了一维,它的计算公式是

s[i][j]=s[i-1][j]+v[i][j]+s[i][j-1]-s[i-1][j-1];

为什么最后还要减?如果你画个图,你就会发现我们加了他两遍

我们可以用二维前缀和计算矩形面积

s{x1,y1,x2,y2}=s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]

知道了这点,我们就可以把问题变成了求最大的正方形面积,最后开个方即可。

-----------------------------------------------------

 1 #include<iostream>
 2 using namespace std;
 3 int s[101][101];
 4 int n,m;
 5 int map[101][101];
 6 int now;
 7 int ans;
 8 int l;
 9 int main(){
10     cin>>n>>m;
11     for(int i=1;i<=n;++i){
12         for(int j=1;j<=m;++j)
13         {
14             cin>>now;
15             map[i][j]=now;
16             s[i][j]=(s[i-1][j]+s[i][j-1]-s[i-1][j-1]+now);//二维前缀和    
17         }
18     }
19     
20     for(int i=1;i<=n;++i)
21     {
22         for(int j=1;j<=m;++j)
23             if(map[i][j]==1){//找到1 
24                 l=1;
25                 ans=max(ans,l);
26                 for(int k=1;(i+k)<=n&&(j+k)<=m;++k){//注意边界条件 
27                     if(
28                     s[i+k][j+k]-s[i-1][j+k]-s[i+k][j-1]+s[i-1][j-1]==
29                     (k+1)*(k+1)//如果相等,就证明是个正方形 
30                     )
31                     {
32                         l++;//尝试下一种可能 
33                         ans=max(ans,l);
34                     }
35                 }
36             }
37         
38     }
39     cout<<ans;
40     return 0; 
41 } 
Ac
原文地址:https://www.cnblogs.com/For-Miku/p/11236756.html