赞
踩
暴力:这题可以暴力写一下,求一个前缀和,然后枚举子矩阵,时间复杂度是 O ( n 4 ) O(n^4) O(n4),显然过不了。
正解:这个题考的是一个双指针,枚举一下矩阵中的左右边界,在每一个左右边界中,从上往下求一下子段中小于等于 k k k 的数的数量(用双指针扫一下就可以,这一步可以做到 O ( n ) O(n) O(n))时间复杂度为 O ( n 3 ) O(n^3) O(n3)。
#include <bits/stdc++.h> #define endl "\n" #define mem(vis, num) memset(vis, num, sizeof(vis)); #define map mapp using namespace std; typedef long long ll; int a[505][505]; int main() { //freopen(".in","r",stdin); //freopen(".out","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m, k; cin >> n >> m >> k; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) cin >> a[i][j]; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) a[i][j] += a[i][j - 1]; ll cnt = 0; for(int i = 1; i <= m; i ++) for(int j = i; j <= m; j ++) { int res = 0; for(int l = 1, r = 1; r <= n; r ++) { res += a[r][j] - a[r][i - 1]; while(res > k && l <= r) { res -= a[l][j] - a[l][i - 1]; l ++; } if(res <= k && l <= r) cnt += r - l + 1; } } cout << cnt; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。