ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】统计子矩阵

2022-07-05 22:34:10  阅读:171  来源: 互联网

标签:int 题解 矩阵 long x2 y1 510 y2 统计


试题 F: 统计子矩阵

时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分

【问题描述】

给定一个 N × M 的矩阵 A,请你统计有多少个子矩阵 (最小 1 × 1,最大
N × M) 满足子矩阵中所有数的和不超过给定的整数 K?

【输入格式】

第一行包含三个整数 N, M 和 K.
之后 N 行每行包含 M 个整数,代表矩阵 A.

【输出格式】

一个整数代表答案。

【样例输入】

3 4 10
1 2 3 4
5 6 7 8
9 10 11 12

【样例输出】

19

【样例说明】

满足条件的子矩阵一共有 19,包含:
大小为 1 × 1 的有 10 个。
大小为 1 × 2 的有 3 个。
大小为 1 × 3 的有 2 个。
大小为 1 × 4 的有 1 个。
大小为 2 × 1 的有 3 个。

【评测用例规模与约定】

对于 30% 的数据,N, M ≤ 20.
对于 70% 的数据,N, M ≤ 100.
对于 100% 的数据,1 ≤ N, M ≤ 500; 0 ≤ Ai j ≤ 1000; 1 ≤ K ≤ 250000000.


30分思路

朴素做法:5重循环暴力求解


70分思路:

预处理二维前缀和,枚举对角线
时间复杂度:O(nnmm(m+1)(n+1)/4)~O(nnnmmm/4);

70分代码

#include<cstdio>
#include<iostream>
using namespace std;
int n,m,k,a[510][510],s[510][510];
int ans,f[510][510];
int get(int x1,int y1,int x2,int y2)
{
	return s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
}

int main()
{
     cin>>n>>m>>k;
     for(int i=1;i<=n;i++)
     {
     	for(int j=1;j<=m;j++)
     	{
     		cin>>a[i][j];
     		s[i][j]+=a[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
		}
	 }
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			for(int ii=0;ii<=n-i;ii++)
			{
				for(int jj=0;jj<=m-j;jj++)
				{
					int x1=i,y1=j,x2=i+ii,y2=j+jj;
					if(get(x1,y1,x2,y2)<=k) f[i][j]++;
			
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(f[i][j]) ans+=f[i][j];
		
		}
	}
	cout<<ans;
	return 0;
}

100分思路

二维前缀和+枚举上下界 双指针左右查找

时间复杂度O(nnm)

100分AC代码:

#include<cstdio>
#include<iostream>
using namespace std;
int n,m,k,a[510][510],s[510][510];
long long ans,f[510][510];
#define ll long long
long long get(int x1,int y1,int x2,int y2)
{
    return s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
}

int main()
{
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
     	{
     	    cin>>a[i][j];
     		s[i][j]+=a[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
	}
    }
    for(int l=1;l<=m;l++)
    {
        for(int r=l;r<=m;r++)
        {
	    int j=1;
	    for(int i=1;i<=n;i++)
	    {
	        while(j<=i&&1ll*get(j,l,i,r)>k) j++;
	        ans+=(i-j+1);
            }
        }
    }
  /*for(int i=1;i<=n;i++)
    {
	for(int j=1;j<=m;j++)
	{
	    if(f[i][j]) ans+=f[i][j];
	}
    }*/
    cout<<ans;
    return 0;
}

标签:int,题解,矩阵,long,x2,y1,510,y2,统计
来源: https://www.cnblogs.com/watasky/p/16448891.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有