Gym 102152L

题意:
给一个 n ∗ m n*m nm矩阵数组,让求子矩阵大小为 h ∗ w h*w hw的最小中位数,确保 n ∗ m n*m nm为奇数。

思路:
二分+求二维数组的前缀和。
二分答案x,然后判断二维矩阵中那个大于x的位置为1,然后二维矩阵的前缀和,二分大于x的数量,若子矩阵中有数量大于 ( h ∗ w + 1 ) / 2 (h*w+1)/2 (hw+1)/2则缩小,反则扩大。

参考代码:

/*
 * @Author: vain
 * @Date: 2020-08-26 11:58:46
 * @LastEditTime: 2020-09-10 19:04:49
 * @LastEditors: sueRimn
 * @Description: In User Settings Edit
 * @FilePath: \main\demo.cpp
 */
//#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
//#define ll long long
typedef unsigned long long ull;
const int N = 1e3 + 20;
const ll maxn = 1e5 + 20;
const ll mod = 1e9 + 7;
ll head[maxn], stac[maxn];
int a[maxn], b[maxn], c[maxn];
//typedef pair p;
//priority_queue, greater

> m; //ll sum[maxn]; int max(int a, int b) { return a > b ? a : b; } ll min(ll a, ll b) { return a < b ? a : b; } ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } ll lcm(ll a, ll b) { return a * b / gcd(a, b); } void swap(ll &x, ll &y) { x ^= y, y ^= x, x ^= y; } map<string, ll> pll, che, mp; int ik[N], q[N], cnt; int lowbit(int x) { return (x) & (-x); } vector<int> fc; //ull h[maxn], p[maxn]; const ull base = 13331; //char s1[maxn]; ll ksm(ll a, ll b) { ll res = 1; while (b) { if (b & 1) res = a * res; b >>= 1; a = a * a; } return res; } int f[N][N], solv[N][N], stk[N]; int get(int x) { int ans = 0; while (x) { if (x & 1) ans++; x >>= 1; } return ans; } void init(int x, int n, int m) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (f[i][j] <= x) solv[i][j] = 1; else solv[i][j] = 0; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { solv[i][j] = solv[i][j - 1] + solv[i - 1][j] - solv[i - 1][j - 1] + solv[i][j]; } } } bool check(int x, int n, int m, int h, int w) { init(x, n, m); for (int i = h; i <= n; i++) { for (int j = w; j <= m; j++) { int ans = solv[i][j] - solv[i][j - w] - solv[i - h][j] + solv[i - h][j - w]; if (ans >= (h * w + 1) / 2) return true; } } return false; } int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); srand(time(NULL)); //cout << ksm(2, 20) << endl; int n, m, t, s, q, h, w; cin >> n >> m >> h >> w; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> f[i][j]; } } int l = 1, r = n * m, ans = 0; while (l <= r) { int mid = l + r >> 1; if (check(mid, n, m, h, w)) { ans = mid, r = mid - 1; } else l = mid + 1; } cout << ans << endl; // cin >> t;zz // while (t--) // { // } }

你可能感兴趣的:(Gym 102152L)