UVA - 12265Selling Land(暴力)
B - Selling Land
As you may know, the country of Absurdistanis full of abnormalities. For example, the whole country can be divided intounit squares that are either grass or swamp. Also, the country is famous forits incapable bureaucrats. If you want to buy a piece of land (called aparcel), you can only buy a rectangular area, because they cannot handle othershapes. The price of the parcel is determined by them and is proportional tothe perimeter of the parcel, since the bureaucrats are unable to multiplyintegers and thus cannot calculate the area of the parcel.
Per owns a parcel in Absurdistan surroundedby swamp and he wants to sell it, possibly in parts, to some buyers. When hesells a rectangular part of his land, he is obliged to announce this to thelocal bureaucrats. They will first tell him the price he is supposed to sell itfor. Then they will write down the name of the new owner and the coordinates ofthe south-east corner of the parcel being sold. If somebody else already owns aparcel with a south-east corner at the same spot, the bureaucrats will deny thechange of ownership.
Per realizes that he can easily trick thesystem. He can sell overlapping areas, because bureaucrats only check whetherthe south-east corners are identical. However, nobody wants to buy a parcelcontaining swamp.
Figure 1: In this example, dark squaresrepresent swamp. Per may, for example, sell three overlapping grey areas, withdimensions 2×1, 2×4 and 4×1 respectively. The total perimeter is 6 + 12 +10=28. Note that he can get more money by selling even more land. This figurecorresponds to the case in the sample input.
Now Per would like to know how many parcelsof each perimeter he needs to sell in order to maximize his profit. Can youhelp him? You may assume that he can always find a buyer for each piece ofland, as long as it doesn't contain any swamps. Also, Per is sure that nosquare within his parcel is owned by somebody else.
Input
On the first line a positive integer: thenumber of test cases, at most 100. After that per test case:
- One line with two integers n and m (1 ≤ n, m ≤ 1 000): the dimensions of Per's parcel.
- n lines, each with m characters. Each character is either `#' or `.'. The j-th character on the i-th line is a `#' if position (i, j) is a swamp, and `.' if it is grass. The north-west corner of Per's parcel has coordinates (1, 1), and the south-east corner has coordinates (n,m).
Output
Per test case:
- Zero or more lines containing a complete list of how many parcels of each perimeter Per needs to sell in order to maximize his profit. More specifically, if Per should sell piparcels of perimeter i in the optimal solution, output a single line "pi x i". The lines should be sorted in increasing order of i. No two lines should have the same value of i, and you should not output lines with pi=0.
Sample in- and output
Input |
Output |
1 6 5 ..#.# .#... #..## ...#. #.... #..#. |
6 x 4 5 x 6 5 x 8 3 x 10 1 x 12 |
题目大意,从右下角向外画长方形,使其周长尽量大。求出整张图中的周长尽量大的长方形的数量和其周长。
乍一看,这题应该是要用个单调栈什么的操作一下,但是实际上。我们可以发现,即便是最大的其实就算直接暴力,最坏情况也才:
多次运算。而题目给了三秒。emmmmm
直接暴力吧。
AC代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
char mm[1005][1005];
int up[1005][1005];
int ans[4005];
const int INF=0x3f3f3f3f;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
memset(up,0,sizeof(up));
memset(mm,0,sizeof(mm));
fill(ans,ans+4005,0);
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",mm[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(i==0&&mm[i][j]=='.')
{
up[i][j]=0;
continue;
}
if(mm[i][j]=='#') up[i][j]=INF;
else
{
if(i<up[i-1][j])
{
up[i][j]=i;
}
else
{
up[i][j]=up[i-1][j];
}
}
//cout<<up[i][j]<<' ';
}
//cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mm[i][j]=='.')
{
int l=j,u=up[i][j];
int s=0;
while(l>=0&&mm[i][l]=='.')
{
u=max(u,up[i][l]);
s=max(s,2*((i+1-u)+(j+1-l)));
l--;
}
l++;
//printf("%d %d ",i,j);
//cout<<u<<' '<<(i+1-u)<<' '<<l<<' '<<(j+1-l)<<' ';
//cout<<2*((i+1-u)+(j+1-l))<<endl;;
ans[s]++;
}
//cout<<' ';
}
//cout<<endl;
}
for(int i=0;i<=4000;i++)
{
if(ans[i]!=0)
{
printf("%d x %d\n",ans[i],i);
}
}
}
return 0;
}