「BZOJ3039」玉蟾宫
Description
有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。
这片土地被分成N*M个格子,每个格子里写着’R’或者’F’,R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。
现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着’F’并且面积最大。
但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。
Input
第一行两个整数N,M,表示矩形土地有N行M列。
接下来N行,每行M个用空格隔开的字符’F’或’R’,描述了矩形土地。
Output
输出一个整数,表示你能得到多少银子,即(3*最大’F’矩形土地面积)的值。
Sample Input
5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
Sample Output
45
HINT
对于50%的数据,1<=N,M<=200
对于100%的数据,1<=N,M<=1000
代码
n^3超时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#include<iostream> #include<cstdio> using namespace std; int a[1001][1001]; int main() { int n,m,x,ans=0; char ch[1]; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%s",ch); if(ch[0]=='F')a[i][j]=a[i][j-1]+1; else a[i][j]=a[i][j-1]; } for(int i=1;i<=m;i++) for(int j=i;j<=m;j++) { int sum=0; for(int k=1;k<=n;k++) { if(a[k][j]-a[k][i-1]==j-i+1)sum+=j-i+1; else sum=0; ans=max(ans,sum); } } printf("%d",3*ans); return 0; } |
n^2单调栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#include<iostream> #include<cstdio> using namespace std; int a[1001][1001]; int s[1001],l[1001]; int n,m,x,ans=0; void work(int h[]) { int top=0,len=0; s[top]=0;l[top]=0; for(int i=1;i<=m;i++) { if(h[i]>=s[top]){ s[++top]=h[i]; l[top]=1; } else{ len=0; while(top&&s[top]>h[i]) { len+=l[top]; ans=max(ans,len*s[top]); top--; } s[++top]=h[i]; l[top]=len+1; } } len=0; while(top) { len+=l[top]; ans=max(ans,len*s[top]); top--; } } int main() { int p; char ch[1]; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%s",ch); if(ch[0]=='F')a[i][j]=a[i-1][j]+1; } for(int i=1;i<=n;i++)work(a[i]); printf("%d",3*ans); return 0; } |
Subscribe