Largest Allowed Area
A company is looking for land to build its headquarters. It has a lot of money and can buy as
many land patches as it needs. Its goal, however, is finding the largest square region
containing no forest. Unfortunately, there is no such region that is large enough for the
headquarters they want to build.
After negotiation with the government and the evaluation of environmental impacts, the
government allows the company to purchase land with at most one forest patch. In other
words, the company’s goal is now finding the largest square region containing at most one
forest patch.
To facilitate the search process, the company creates a map in the form of a 2D table
consisting R rows and C columns. In this 2D table, each entry represents a land of patch
where 0 corresponds to a non-forest patch and 1 to a forest patch. Unfortunately, the map
may have up to 1,000 x 1,000 entries and it is not a good idea to manually look for the largest
allowed square region. This is where your skill comes into play. Write an efficient algorithm
to find such a square region.
Input:
The first line is a positive integer T <= 20 representing the number of test cases. For each
case, the input is formatted as follows.
First line R C
where R and C represents the number of rows and columns in the
map. Also, 5 <= R, C <= 1,000
Next R lines Each line represents a row in the map from the first to last. It has C
numbers which are 0 or 1, separated by one space.
Note: there is at least one non-forest patch in each test case.
Output:
There are T lines in the output. Each line is the number of rows in the largest allowed square
region for each case.
2018 ICPC
Asia Nakhon Pathom
Regional Contest
Problem L
Largest Allowed Area
Time Limit 1 sec
2018 ICPC Asia Nakhon Pathom Regional Contest
Sample Input/Output
Input Output
2
10 20
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
20 10
1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
https://vjudge.net/contest/326230#problem/L
題意:求一個最大正方形矩陣,矩陣和不超過1
二維前綴和遞推公式:dp[i][j] = dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+map[i][j]
求x1,y1到x2,y2的區間和:ans = dp[x2][y2]-dp[x2][y1-1]-dp[x1-1][y2]+dp[x1-1][x2-1]
先求出二維前綴和,再對正方形的邊長二分找到答案
#include<bits/stdc++.h>
using namespace std;
int a[1200][1200],dp[1200][1200],n,m;
bool Find(int num)
{
for(int i = 1; i <=n; i ++)
{
if(i+num-1> n)
break;
for(int j = 1; j <= m; j ++)
{
if(j+num-1> m)
break;
int sum = dp[i+num-1][j+num-1]+dp[i-1][j-1]-dp[i+num-1][j-1]-dp[i-1][j+num-1];
if(sum <= 1)
return 1;
}
}
return 0;
}
int main()
{
int i,j,t;
char ch;
scanf("%d",&t);
while(t --)
{
scanf("%d %d",&n, &m);
for(i = 1; i <= max(n,m); i ++)
{
dp[i][0] = dp[0][i] = 0;
}
for(i = 1; i <= n; i ++)
{
for(j = 1; j <= m; j ++)
{
ch = getchar();
while(ch!='0'&&ch!='1')
ch = getchar();
a[i][j] = ch-'0';
}
}
for(i = 1; i <= n; i ++)
{
for(j = 1; j <= m; j ++)
{
dp[i][j] = dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+a[i][j];
}
}
int l = 1;
int r = min(n,m);
int ans = -1;
while(l <= r)
{
int mid = (l+r)>>1;
if(Find(mid))
{
ans = mid;
l = mid+1;
}
else
r = mid-1;
}
printf("%d\n",ans);
}
return 0;
}