• 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
    ");
     16 #define pn printf("
    ");
     17 #define pk printf(" ");
     18 #define p(n) printf("%d",n);
     19 #define pln(n) printf("%d
    ",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 }
    其他大佬代码:
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 int n,m,g;
     5 int a[505][505];
     6 int b[505][505];//最大值
     7 int c[505][505];//最小值
     8 int b1[505][505];
     9 int c1[505][505];
    10 
    11 int l;
    12 int main()
    13 {
    14     scanf("%d%d%d",&n,&m,&g);
    15     for(int i=1;i<=n;i++){
    16         for(int j=1;j<=m;j++){
    17             scanf("%d",&a[i][j]);
    18             if(i>=2&&j>=2){
    19                 b[i-1][j-1] = max(a[i][j], max(a[i-1][j], max(a[i][j-1],a[i-1][j-1]) ) );
    20                 c[i-1][j-1] = min(a[i][j], min(a[i-1][j], min(a[i][j-1],a[i-1][j-1]) ) );
    21             }
    22         }
    23     }
    24 
    25     int x = n-1;
    26     int y = m-1;
    27     l = min(n,m);
    28     int ans = 1;
    29     for(int i = 2; i <= l;i++)
    30     {
    31 
    32         for(int j = 1;j <= x;j++)
    33         {
    34             for(int k = 1;k <= y;k++)
    35             {
    36                 if(b[j][k] - c[j][k] <= g){
    37                     ans = i;
    38                 }
    39             }
    40         }
    41 
    42         for(int j = 2;j <= x;j++)
    43         {
    44             for(int k = 2;k <= y;k++)
    45             {
    46                 b1[j][k] = max(b[j][k] , max(b[j-1][k],max(b[j][k-1],b[j-1][k-1])));
    47                 b[j-1][k-1] = b1[j][k];
    48                 c1[j][k] = min(c[j][k] , min(c[j-1][k],min(c[j][k-1],c[j-1][k-1])));
    49                 c[j-1][k-1] = c1[j][k];
    50             }
    51         }
    52         x--;
    53         y--;
    54     }
    55     cout<<ans<<endl;
    56 
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    动态规划
    Python第二天学习
    Python第一天学习---基础语法
    java易错知识点
    C语言---指针复习
    排序汇总
    课程设计---创建族谱管理系统
    Vue第五篇 Vue的生命周期
    Vue第四篇 Vue路由系统
    Vue第三篇 Vue组件
  • 原文地址:https://www.cnblogs.com/Kidgzz/p/10744930.html
Copyright © 2020-2023  润新知