SPOJ - MINSUB——单调栈+01矩阵变换

2024-04-07 01:08
文章标签 01 矩阵 单调 变换 spoj minsub

本文主要是介绍SPOJ - MINSUB——单调栈+01矩阵变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

You are given an matrix M (consisting of nonnegative integers) and an integer K. For any submatrix of M’ of M define min(M’) to be the minimum value of all the entries of M’. Now your task is simple: find the maximum value of min(M’) where M’ is a submatrix of M of area at least K (where the area of a submatrix is equal to the number of rows times the number of columns it has).

Input
The first line contains a single integer T (T ≤ 10) denoting the number of test cases, T test cases follow. Each test case starts with a line containing three integers, R (R ≤ 1000), C (C ≤ 1000) and K (K ≤ R * C) which represent the number of rows, columns of the matrix and the parameter K. Then follow R lines each containing C nonnegative integers, representing the elements of the matrix M. Each element of M is ≤ 10^9

Output
For each test case output two integers: the maximum value of min(M’), where M’ is a submatrix of M of area at least K, and the maximum area of a submatrix which attains the maximum value of min(M’). Output a single space between the two integers.

Example
Input:
2
2 2 2
1 1
1 1
3 3 2
1 2 3
4 5 6
7 8 9

Output:
1 4
8 2
到现在为止还没有好好做过矩阵的单调栈,而且一上来就是一道比较可以的题目,也只能看看别人的题解
来做提了。
以前博客好像也写过,求最大的最小值或最小的最大值一般来说就是二分了,我们二分值的大小,然后将小于二分值的a数组里面的值赋为0,其他的赋为1,然后就是01矩阵求最大子矩阵的题目了。

#include<iostream>
#include<stack>
#include<cstdio>
#include<cstring>
using namespace std;
stack<int>st;
int a[1005][1005],f[1005][1005],r,c,k;
int check(int x)
{for(int i=1;i<=r;i++)for(int j=1;j<=c;j++)f[i][j]=(a[i][j]>=x)?f[i-1][j]+1:0;int maxn=0;for(int i=1;i<=r;i++){while(!st.empty())st.pop();//将上次的值清除。for(int j=1;j<=c+1;j++){while(!st.empty()&&f[i][st.top()]>f[i][j]){int t=st.top();st.pop();if(st.empty())maxn=max(maxn,f[i][t]*(j-1));elsemaxn=max(maxn,f[i][t]*(j-1-st.top()));//刚开始一直不知道这是什么意思,自己调试了一下才发现
如果我们把j循环到c就停止了的话,那么如果两列的f是相同的,那就不会进入if语句,所以要变大一位。
然后这个j-1-st.top()就是列数,而f[i][t]就是之前的行数,因为是单调栈,
所以t肯定不比当前的行数大,看看能取到多少个列是有的情况,就是!st.empty()。}st.push(j);}}return maxn; 
}
int main()
{int t;scanf("%d",&t);while(t--){while(!st.empty())st.pop();memset(f,0,sizeof(f));int low=1e9,high=0,mid;scanf("%d%d%d",&r,&c,&k);for(int i=1;i<=r;i++)for(int j=1;j<=c;j++){scanf("%d",&a[i][j]);low=min(low,a[i][j]);high=max(high,a[i][j]);}int ans=0;while(high>=low){mid=low+high>>1;if(check(mid)>=k){low=mid+1;ans=mid;}elsehigh=mid-1;}printf("%d %d\n",ans,check(ans));}return 0;
}

这篇关于SPOJ - MINSUB——单调栈+01矩阵变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/881287

相关文章

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

集中式版本控制与分布式版本控制——Git 学习笔记01

什么是版本控制 如果你用 Microsoft Word 写过东西,那你八成会有这样的经历: 想删除一段文字,又怕将来这段文字有用,怎么办呢?有一个办法,先把当前文件“另存为”一个文件,然后继续改,改到某个程度,再“另存为”一个文件。就这样改着、存着……最后你的 Word 文档变成了这样: 过了几天,你想找回被删除的文字,但是已经记不清保存在哪个文件了,只能挨个去找。真麻烦,眼睛都花了。看

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

01 Docker概念和部署

目录 1.1 Docker 概述 1.1.1 Docker 的优势 1.1.2 镜像 1.1.3 容器 1.1.4 仓库 1.2 安装 Docker 1.2.1 配置和安装依赖环境 1.3镜像操作 1.3.1 搜索镜像 1.3.2 获取镜像 1.3.3 查看镜像 1.3.4 给镜像重命名 1.3.5 存储,载入镜像和删除镜像 1.4 Doecker容器操作 1.4

线性代数|机器学习-P35距离矩阵和普鲁克问题

文章目录 1. 距离矩阵2. 正交普鲁克问题3. 实例说明 1. 距离矩阵 假设有三个点 x 1 , x 2 , x 3 x_1,x_2,x_3 x1​,x2​,x3​,三个点距离如下: ∣ ∣ x 1 − x 2 ∣ ∣ 2 = 1 , ∣ ∣ x 2 − x 3 ∣ ∣ 2 = 1 , ∣ ∣ x 1 − x 3 ∣ ∣ 2 = 6 \begin{equation} ||x