第十三届蓝桥杯c++b组-统计子矩阵

题目描述
给定一个 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

思路:看见这个题,直接想到了二维前缀和,然后就超时了。。。然后用到了一维前缀和+双向指针。
,感觉前几个题都在模拟的路上。

二维前缀和超时代码:

import java.util.Scanner;
public class Main {
    
    
	static int N = 200005;
	static int[]a = new int[N];
	static int[]b = new int[N];
	public static void main(String[] args) {
    
    
		new Main().solve();
	}
	
	void solve() {
    
    
		int mod =1000000007;
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int arr[][] = new int[n+1][m+1];
		int sum[][] = new int[n+1][m+1];
		for(int i=1;i<=n;i++) {
    
    
			for(int j=1;j<=m;j++) {
    
    
				arr[i][j] = sc.nextInt();
				sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+arr[i][j];
			}
		}
//		for(int i=1;i<=n;i++) {
    
    
//			for(int j=1;j<=m;j++) {
    
    
//				System.out.print(sum[i][j]+" ");
//			}
//			System.out.println();
//		}
		long t = 0;
		for(int i=1;i<=n;i++) {
    
    
			for(int j=1;j<=m;j++) {
    
    
				for(int ii=i;ii<=n;ii++) {
    
    
					for(int jj=j;jj<=m;jj++) {
    
    
						if((sum[ii][jj]-sum[i-1][jj]-sum[ii][j-1]+sum[i-1][j-1])<=k) {
    
    
							t++;
						}else {
    
    
							break;
						}
					}
				}
			}
		}
		System.out.println(t);
		sc.close();
	}
}

AC代码:

import java.util.Scanner;
public class Main {
    
    
	static int N = 200005;
	static int[]a = new int[N];
	static int[]b = new int[N];
	public static void main(String[] args) {
    
    
		new Main().solve();
	}
	
	void solve() {
    
    
		int mod =1000000007;
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int arr[][] = new int[n+1][m+1];
		int sum[][] = new int[n+1][m+1];
		for(int i=1;i<=n;i++) {
    
    
			for(int j=1;j<=m;j++) {
    
    
				arr[i][j] = sc.nextInt();
				sum[i][j] += sum[i-1][j]+arr[i][j];
			}
		}
//		for(int i=1;i<=n;i++) {
    
    
//			for(int j=1;j<=m;j++) {
    
    
//				System.out.print(sum[i][j]+" ");
//			}
//			System.out.println();
//		}
		long t = 0;
		for(int i=1;i<=n;i++) {
    
    
			for(int j=i;j<=n;j++) {
    
    
				int res=0;
				for(int l=1,r=1;r<=m;r++) {
    
    
					res += sum[j][r]-sum[i-1][r];
					while(res>k) {
    
    
						res-=sum[j][l]-sum[i-1][l];
						l++;
					}
					t+=r-l+1;
				}
			}
		}
		System.out.println(t);
		sc.close();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_52237775/article/details/127939922