ZOJ 题目2859 Matrix Searching(二维RMQ)

来源:互联网 发布:表亲结婚知乎 编辑:程序博客网 时间:2024/05/21 12:30
Matrix Searching

Time Limit: 10 Seconds      Memory Limit: 32768 KB

Given an n*n matrix A, whose entries Ai,j are integer numbers ( 1 <= i <= n, 1 <= j <= n ). An operation FIND the minimun number in a given ssub-matrix.

Input

The first line of the input contains a single integer T , the number of test cases.

For each test case, the first line contains one integer n (1 <= n <= 300), which is the sizes of the matrix, respectively. The next n lines with n integers each gives the elements of the matrix.

The next line contains a single integer N (1 <= N <= 1,000,000), the number of queries. The next N lines give one query on each line, with four integers r1, c1, r2, c2 (1 <= r1 <= r2 <= n, 1 <= c1 <= c2 <= n), which are the indices of the upper-left corner and lower-right corner of the sub-matrix in question.

Output

For each test case, print N lines with one number on each line, the required minimum integer in the sub-matrix.

Sample Input

1
2
2 -1
2 3
2
1 1 2 2
1 1 2 1

Sample Output

-1
2


Author: PENG, Peng

Source: ZOJ Monthly, June 2007

帮学妹找了一晚上的bug,,,各种调试,,各种报错,,感觉自己水爆了,,赶紧水道高级点的水题压压惊~~

ac代码

#include<stdio.h>#include<string.h>#include<math.h>#define max(a,b) (a>b?a:b)#define min(a,b) (a>b?b:a)int map[301][301];int minv[301][301][9][9];int mm[306];int n,m;void initrmq(){int i,j;for(i=1;i<=n;i++){for(j=1;j<=n;j++){minv[i][j][0][0]=map[i][j];}}int ii,jj;for(ii=0;ii<=mm[n];ii++)for(jj=0;jj<=mm[n];jj++){if(ii+jj){for(i=1;i+(1<<ii)-1<=n;i++)for(j=1;j+(1<<jj)-1<=n;j++){if(ii)minv[i][j][ii][jj]=min(minv[i][j][ii-1][jj],minv[i+(1<<(ii-1))][j][ii-1][jj]);elseminv[i][j][ii][jj]=min(minv[i][j][ii][jj-1],minv[i][j+(1<<(jj-1))][ii][jj-1]);}}}}int q_min(int x1,int y1,int x2,int y2){int k1=mm[x2-x1+1];int k2=mm[y2-y1+1];x2=x2-(1<<k1)+1;y2=y2-(1<<k2)+1;return min(min(minv[x1][y1][k1][k2],minv[x1][y2][k1][k2]),min(minv[x2][y1][k1][k2],minv[x2][y2][k1][k2]));}void init(){mm[0]=-1;int i;  for(i = 1;i <= 305;i++)          mm[i] = ((i&(i-1))==0)?mm[i-1]+1:mm[i-1];  }int main(){int t;init();scanf("%d",&t);while(t--){//int n,m;scanf("%d",&n);int i,j;for(i=1;i<=n;i++){for(j=1;j<=n;j++)scanf("%d",&map[i][j]);}initrmq();scanf("%d",&m);while(m--){int r1,c1,r2,c2;scanf("%d%d%d%d",&r1,&c1,&r2,&c2);printf("%d\n",q_min(r1,c1,r2,c2));}}}


0 0
原创粉丝点击