Minieye杯第十五届华中科技大学程序设计邀请赛现场同步赛 I Matrix Again

Minieye杯第十五届华中科技大学程序设计邀请赛现场同步赛 I Matrix Again

https://ac.nowcoder.com/acm/contest/700/I

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

KK is the engineer responsible for sensor sensing in MINIEYE. KK recently need to use radar to sense the vehicles ahead, and KK thought about it day and night, and finally found a perfect solution.

You are now an intern at KK. To give you an understanding of the principles of radar sensing, KK gives you a simplified version of this problem.

Given a matrix of N×M, each element is an integer. If there is a submatrix of L × L, and the difference between the maximum and the minimum of this submatrix is less than or equal to G, then this submatrix is considered as a car matrix. Now you need to find the largest L.

输入描述:

The first line contains three integers N, M, G(0 < N, M ≤ 500, 0 ≤ G ≤ 200).
Each of the following N lines contains M integers, representing the matrix. It is guaranteed that every integer in the matrix is in the range [-100, 100].

输出描述:

Output the maximum L in a single line.

示例1

输入

3 3 4
0 1 2
3 4 5
6 7 8

输出

2

分析

题目大意就是从一个N*M的矩阵里选取一个L*L的矩阵,使得这个矩阵中的最大值和最小值的差小于等于G,求最大的L。

首先很显然跟RMQ问题,求最大最小值嘛,但是这题是矩阵,那就是二维的RMQ,用ST表实现的,模板++;

在处理完最大最小之后,如果要遍历所有的矩阵时间复杂度过大是不行的,考虑二分,,,然后二分写自闭了,最后还是队友改二分改正确了。

在我打这句话的时候,队内其他大佬用暴力过了这题,,,,,瞬间不想继续写这题的题解了,,,,撤了。

AC代码:

 1 #include <stdio.h>  2 #include <math.h>  3 #include <string.h>  4 #include <algorithm>  5 #include <iostream>  6 #include <string>  7 #include <time.h>  8 #include <queue>  9 #include <list>  10 #include <string.h>  11 #define sf scanf  12 #define pf printf  13 #define lf double  14 #define ll long long  15 #define p123 printf("123\n");  16 #define pn printf("\n");  17 #define pk printf(" ");  18 #define p(n) printf("%d",n);  19 #define pln(n) printf("%d\n",n);  20 #define s(n) scanf("%d",&n);  21 #define ss(n) scanf("%s",n);  22 #define ps(n) printf("%s",n);  23 #define sld(n) scanf("%lld",&n);  24 #define pld(n) printf("%lld",n);  25 #define slf(n) scanf("%lf",&n);  26 #define plf(n) printf("%lf",n);  27 #define sc(n) scanf("%c",&n);  28 #define pc(n) printf("%c",n);  29 #define gc getchar();  30 #define re(n,a) memset(n,a,sizeof(n));  31 #define len(a) strlen(a)  32 #define LL long long  33  34 using namespace std;  35  36 int val[505][505];  37 int mm[505];  38 char dpmin[505][505][9][9];//最小值  39 char dpmax[505][505][9][9];//最大值  40  41 void initRMQ(int n,int m) {  42 for(int i = 1; i <= n; i++)  43 for(int j = 1; j <= m; j++)  44 dpmin[i][j][0][0] = dpmax[i][j][0][0] = val[i][j];  45 for(int ii = 0; ii <= mm[n]; ii++)  46 for(int jj = 0; jj <= mm[m]; jj++)  47 if(ii+jj)  48 for(int i = 1; i + (1<<ii) - 1 <= n; i++)  49 for(int j = 1; j + (1<<jj) - 1 <= m; j++) {  50 if(ii) {  51 dpmin[i][j][ii][jj] = min(dpmin[i][j][ii-1][jj],dpmin[i+(1<<(ii-1))][j][ii-1][jj]);  52 dpmax[i][j][ii][jj] = max(dpmax[i][j][ii-1][jj],dpmax[i+(1<<(ii-1))][j][ii-1][jj]);  53 } else {  54 dpmin[i][j][ii][jj] = min(dpmin[i][j][ii][jj-1],dpmin[i][j+(1<<(jj-1))][ii][jj-1]);  55 dpmax[i][j][ii][jj] = max(dpmax[i][j][ii][jj-1],dpmax[i][j+(1<<(jj-1))][ii][jj-1]);  56  }  57  }  58 }  59 int rmq1(int x1,int y1,int x2,int y2) {  60 int k1 = mm[x2-x1+1];  61 int k2 = mm[y2-y1+1];  62 x2 = x2 - (1<<k1) + 1;  63 y2 = y2 - (1<<k2) + 1;  64 return max(max(dpmax[x1][y1][k1][k2],dpmax[x1][y2][k1][k2]),max(dpmax[x2][y1][k1][k2],dpmax[x2][y2][k1][k2]));  65 }  66 //查询矩形的最小值  67 int rmq2(int x1,int y1,int x2,int y2) {  68 int k1 = mm[x2-x1+1];  69 int k2 = mm[y2-y1+1];  70 x2 = x2 - (1<<k1) + 1;  71 y2 = y2 - (1<<k2) + 1;  72 return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2]));  73 }  74  75 int main() {  76 mm[0] = -1;  77 for(int i = 1; i <= 500; i++)  78 mm[i] = ((i&(i-1))==0)?mm[i-1]+1:mm[i-1];  79 int N,M,g;  80 scanf("%d%d%d",&N,&M,&g);  81 for(int i = 1; i <= N; i++)  82 for(int j = 1; j <= M; j++)  83 scanf("%d",&val[i][j]);  84  initRMQ(N,M);  85 //123456  86 int x,y;  87 int maxi = -1;  88 for(int i = 1; i <= N; i++) {  89 for(int j = 1; j <= M; j++) {  90 int l = 1,r = min(N-i+1,M-j+1),mid;  91 int ans;  92 while(l <= r) {  93 mid = (l+r) >> 1;  94 if(rmq1(i,j,i+mid-1,j+mid-1)-rmq2(i,j,i+mid-1,j+mid-1) > g) {  95 r = mid-1;  96 //ans = mid;  97 } else {  98 l = mid+1;  99  } 100  } 101 if(r > maxi) { 102 maxi = r; 103  } 104  } 105  } 106  p(maxi) pn 107 108 return 0; 109 }
其他大佬代码:
View Code

 

全部评论

相关推荐

预计下个星期就能开奖吧,哪位老哥来给个准信
华孝子爱信等:对接人上周说的是这周
点赞 评论 收藏
分享
10-07 20:48
门头沟学院 Java
听说改名就会有offer:可能是实习上着班想到后面还要回学校给导师做牛马,看着身边都是21-25的年纪,突然emo了了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务