Gym 101102D Rectangles 【单调栈】
2016-10-04 11:03
232 查看
Description
standard input/output
Given an R×C grid with each cell containing an integer, find the number of subrectangles in this grid that contain only one distinct integer; this means every cell in a subrectangle
contains the same integer.
A subrectangle is defined by two cells: the top left cell
(r1, c1), and the bottom-right cell
(r2, c2)
(1 ≤ r1 ≤ r2 ≤ R)
(1 ≤ c1 ≤ c2 ≤ C), assuming that rows are numbered from top to bottom and columns are numbered from left to right.
Input
The first line of input contains a single integer T, the number of test cases.
The first line of each test case contains two integers
R and C
(1 ≤ R, C ≤ 1000), the number of rows and the number of columns of the grid, respectively.
Each of the next R lines contains
C integers between 1 and
109, representing the values in the row.
Output
For each test case, print the answer on a single line.
Sample Input
Input
Output
求出由相同数字组成的矩形的个数
一看到这题就想到了这个题:
单调栈优化dp:hdu1506Largest Rectangle in a Histogram &hdu1505city game dp ||附面试题:柱子围水|柱子围面积
原题只是求最大的,对于维护的单调栈每次比较面积即可。而对于这个题,我们维护单调栈的值依旧是列序号。我们设ans[i][j]表示以(i,j)为右下角点的可组成矩阵个数,假设在(i,j)左边离它最近的高度比它小的位置是(i,p)那么ans[i][j]=ans[i][k]+(j-k)*h[i][j]。但是如果(i,j)和(i,k)不是同一种图案就不能加进去啦
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[1005][1005],ans[1005][1005],h[1005][1005];
int s[1005],pos[1005];
int main()
{
// freopen("cin.txt","r",stdin);
int t,r,c;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&r,&c);
memset(h,0,sizeof(h));
memset(ans,0,sizeof(ans));
memset(a,0,sizeof(a));
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
scanf("%d",&a[i][j]);
if(a[i-1][j]!=a[i][j])h[i][j]=1;
else h[i][j]=h[i-1][j]+1;
}
}
//for(int i=1;i<=r;i++){for(int j=1;j<=c;j++)printf("%d ",h[i][j]);puts(""); }
int num;
long long sum=0;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
if(a[i][j-1]!=a[i][j])
{
num=1;
s[1]=j-1;//
h[i][j-1]=0;//
s[++num]=j;
//pos[j]=j-1;//
ans[i][j]=h[i][j];//
sum+=(long long)ans[i][j];
}
else
{
while(h[i][j]<=h[i][s[num]])num--;
int p=s[num];
s[++num]=j;
ans[i][j]+=h[i][j]*(j-p);
if(h[i][p]!=0)ans[i][j]+=ans[i][p];
sum+=ans[i][j]*1LL;
}
}
}
printf("%I64d\n",sum);
}
return 0;
}
standard input/output
Given an R×C grid with each cell containing an integer, find the number of subrectangles in this grid that contain only one distinct integer; this means every cell in a subrectangle
contains the same integer.
A subrectangle is defined by two cells: the top left cell
(r1, c1), and the bottom-right cell
(r2, c2)
(1 ≤ r1 ≤ r2 ≤ R)
(1 ≤ c1 ≤ c2 ≤ C), assuming that rows are numbered from top to bottom and columns are numbered from left to right.
Input
The first line of input contains a single integer T, the number of test cases.
The first line of each test case contains two integers
R and C
(1 ≤ R, C ≤ 1000), the number of rows and the number of columns of the grid, respectively.
Each of the next R lines contains
C integers between 1 and
109, representing the values in the row.
Output
For each test case, print the answer on a single line.
Sample Input
Input
1 3 3 3 3 1 3 3 1 2 2 5
Output
16
求出由相同数字组成的矩形的个数
一看到这题就想到了这个题:
单调栈优化dp:hdu1506Largest Rectangle in a Histogram &hdu1505city game dp ||附面试题:柱子围水|柱子围面积
原题只是求最大的,对于维护的单调栈每次比较面积即可。而对于这个题,我们维护单调栈的值依旧是列序号。我们设ans[i][j]表示以(i,j)为右下角点的可组成矩阵个数,假设在(i,j)左边离它最近的高度比它小的位置是(i,p)那么ans[i][j]=ans[i][k]+(j-k)*h[i][j]。但是如果(i,j)和(i,k)不是同一种图案就不能加进去啦#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[1005][1005],ans[1005][1005],h[1005][1005];
int s[1005],pos[1005];
int main()
{
// freopen("cin.txt","r",stdin);
int t,r,c;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&r,&c);
memset(h,0,sizeof(h));
memset(ans,0,sizeof(ans));
memset(a,0,sizeof(a));
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
scanf("%d",&a[i][j]);
if(a[i-1][j]!=a[i][j])h[i][j]=1;
else h[i][j]=h[i-1][j]+1;
}
}
//for(int i=1;i<=r;i++){for(int j=1;j<=c;j++)printf("%d ",h[i][j]);puts(""); }
int num;
long long sum=0;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
if(a[i][j-1]!=a[i][j])
{
num=1;
s[1]=j-1;//
h[i][j-1]=0;//
s[++num]=j;
//pos[j]=j-1;//
ans[i][j]=h[i][j];//
sum+=(long long)ans[i][j];
}
else
{
while(h[i][j]<=h[i][s[num]])num--;
int p=s[num];
s[++num]=j;
ans[i][j]+=h[i][j]*(j-p);
if(h[i][p]!=0)ans[i][j]+=ans[i][p];
sum+=ans[i][j]*1LL;
}
}
}
printf("%I64d\n",sum);
}
return 0;
}
相关文章推荐
- CodeforcesGym - 101102D. Rectangles 单调栈+dp优化
- Codeforces gym 101102 D 单调栈
- Gym 101102D---Rectangles(单调栈)
- GYM 101102 D.Rectangles(单调栈)
- Gym 101102D 单调栈
- GYM 100801J Journey to the “The World's Start”【二分+Dp+单调队列】
- Gym 100971D Laying Cables 二分 || 单调栈
- Codeforces gym 101102 A dp
- B - The Little Match Girl Gym - 101102B 枚举技巧 火柴棒问题
- GYM 101102 I.Simple Robot(水~)
- Codeforces gym 101102 K 想法
- Gym - 101102B B. The Little Match Girl 贪心、数论、分步
- GYM 101102 J.Divisible Numbers(数论+容斥原理)
- Gym - 101102B-------枚举法
- BZOJ 3885 Usaco2015 Jan Cow Rectangles 单调队列+二分
- Gym 100342E Minima (暴力,单调队列)
- GYM 101102 K.Topological Sort(线段树)
- Gym 100712L Alternating Strings II(单调队列)
- Codeforces gym 100971 D. Laying Cables 单调栈
- GYM 101102 A.Coins(01背包)