Check Corners
Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2424 Accepted Submission(s): 881
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 yes4 yes
题意:n,m是矩阵的长宽,然后给出一个矩阵。 q次询问,每次给出矩阵的左上角坐标和右下角坐标,求在这个小矩阵里的最大值,还有这个最大值是否是矩阵四个角其中之一。
思路:普通的RMQ用来求一个区间的最大值,这里是平面问题,于是想到用二维RMQ来求四边形的最大值。写法和一维差不多,细节多注意下就好。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; #define N 305 int ma[N][N]; int dp[N][N][9][9]; int maxs(int a,int b,int c,int d) { int maxn=a; if(b>maxn) maxn=b; if(c>maxn) maxn=c; if(d>maxn) maxn=d; return maxn; } void makermq(int m,int n) { for(int i=0; i<m; i++) for(int j=0; j<n; j++) dp[i][j][0][0]=ma[i][j]; for(int q=0; (1<<q)<=m; q++) { for(int w=0; (1<<w)<=n; w++) { if(q==0&&w==0) continue; for(int j=0; j+(1<<q)-1<m; j++) { for(int i=0; i+(1<<w)-1<n; i++) { if(q==0) dp[j][i][q][w]=max(dp[j][i][q][w-1],dp[j][i+(1<<(w-1))][q][w-1]); else if(w==0) dp[j][i][q][w]=max(dp[j][i][q-1][w],dp[j+(1<<(q-1))][i][q-1][w]); else dp[j][i][q][w]=maxs(dp[j][i][q-1][w],dp[j+(1<<(q-1))][i][q-1][w], dp[j][i][q][w-1],dp[j][i+(1<<(w-1))][q][w-1]); } } } } } int finds(int x1,int y1,int x2,int y2) { int k1=(int)(log(x2-x1+1.0)/log(2.0)); int k2=(int)(log(y2-y1+1.0)/log(2.0)); return maxs(dp[x1][y1][k1][k2],dp[x2-(1<<k1)+1][y2-(1<<k2)+1][k1][k2], dp[x1][y2-(1<<k2)+1][k1][k2],dp[x2-(1<<k1)+1][y1][k1][k2]); } int main() { int n,m,q; int x1,y1,x2,y2; while(scanf("%d %d",&m,&n)!=EOF) { for(int i=0; i<m; i++) for(int j=0; j<n; j++) scanf("%d",&ma[i][j]); makermq(m,n); scanf("%d",&q); while(q--) { scanf("%d %d %d %d",&x1,&y1,&x2,&y2); x1--; y1--; x2--; y2--; int ans=finds(x1,y1,x2,y2); printf("%d ",ans); if(ans==ma[x1][y1]||ans==ma[x1][y2]||ans==ma[x2][y1]||ans==ma[x2][y2]) printf("yes\n"); else printf("no\n"); } } return 0; }