Check Corners
Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3063 Accepted Submission(s): 1100
For each test case, the first line contains two integers m, n (1 <= m, n <= 300), which is the size of the row and column of the matrix, respectively. The next m lines with n integers each gives the elements of the matrix which fit in non-negative 32-bit integer.
The next line contains a single integer Q (1 <= Q <= 1,000,000), the number of queries. The next Q lines give one query on each line, with four integers r1, c1, r2, c2 (1 <= r1 <= r2 <= m, 1 <= c1 <= c2 <= n), which are the indices of the upper-left corner and lower-right corner of the sub-matrix in question.
4 4 4 4 10 7 2 13 9 11 5 7 8 20 13 20 8 2 4 1 1 4 4 1 1 3 3 1 3 3 4 1 1 1 1
20 no 13 no 20 yes 4 yes
题意:
给出一个矩阵,给你几个询问,每个询问问你子矩阵中的最大值,若最大值在角上,yes,否则no。
POINT:
二维的RMQ,之前没做过。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
const int N = 300+3;
int n,m;
int a[N][N];
int dp[N][N][9][9];
void prermq()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j][0][0]=a[i][j];
}
}
for(int a=0;1<<a<=n;a++)
{
for(int b=0;1<<b<=m;b++)
{
if(a==b&&b==0) continue;
for(int i=1;i-1+(1<<a)<=n;i++)
{
for(int j=1;j-1+(1<<b)<=m;j++)
{
if(a==0)
{
dp[i][j][a][b]=max(dp[i][j][a][b-1],dp[i][j+(1<<(b-1))][a][b-1]);
}
else
dp[i][j][a][b]=max(dp[i][j][a-1][b],dp[i+(1<<(a-1))][j][a-1][b]);
}
}
}
}
}
int query(int r1,int c1,int r2,int c2)
{
int k1=(int)log2((double)(r2-r1+1));
int k2=(int)log2((double)(c2-c1+1));
int a=dp[r1][c1][k1][k2];
int b=dp[r1][c2+1-(1<<k2)][k1][k2];
int c=dp[r2+1-(1<<k1)][c1][k1][k2];
int d=dp[r2+1-(1<<k1)][c2+1-(1<<k2)][k1][k2];
return max(max(a,b),max(c,d));
}
int ans;
bool f(int x,int y)
{
if(a[x][y]==ans) return 1;
return 0;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
memset(dp,0,sizeof dp);
memset(a,0,sizeof a);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
}
prermq();
int q;
scanf("%d",&q);
while(q--)
{
int r1,c1,r2,c2;
scanf("%d %d %d %d",&r1,&c1,&r2,&c2);
ans=query(r1,c1,r2,c2);
printf("%d ",ans);
if(f(r1,c1)||f(r2,c1)||f(r1,c2)||f(r2,c2))
{
printf("yes\n");
}
else printf("no\n");
}
}
}
598



被折叠的 条评论
为什么被折叠?



