2 条题解

  • 1
    @ 2026-8-20 14:45:43

    没有任何算法的一道,ac 秘诀在于步骤要清晰,尽量简明思路。

    聪明的小朋友肯定想到了用行内前缀和,来判断该行区间是否全部能放人。

    还有通过每列的前缀最大值,来判断当前格子能不能放这个高度的人。

    同时可以给当前行选择区间的前缀最大值排序,和已经排序的 h 数组一个个相应下标匹配,但凡一个出问题,直接否定整个区间。

    好了,打出来却发现 WA 和 TLE 找上门。

    考虑优化,假设列区间已经固定,如果 i 行这个区间可以放人,那么 i 后面的行这个区间只要空的都可以放人。

    即判断能否放人的列区间具有单调性。

    直接二分可以放人的行边界,这个时候先只关注前缀最大值,最后累计答案时再关注空不空。

    复杂度因为要二分和排序,是枚举 * 双 log,也就是 O(N2log2N)O(N^2log^2N)

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int N = 2010;
    
    LL a[N][N];
    LL sum[N][N];
    LL mx[N][N];
    LL h[N];
    LL now[N];
    int n, m, K;
    
    bool check(int x, int y) {
    	for (int j = y; j <= y + K - 1; j ++) {
    		now[j - y + 1] = mx[x][j];
    	}
    	sort(now + 1, now + K + 1);
    	for (int i = 1; i <= K; i ++) {
    		if (h[i] <= now[i]) {
    			return 0;
    		}
    	}
    	return 1;
    }
    
    int main () {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	
    	cin >> n >> m >> K;
    	
    	for (int i = 1; i <= K; i ++) {
    		cin >> h[i];
    	}
    	sort (h + 1, h + K + 1);
    	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 ++) {
    		sum[i][0] = 0;
    		for (int j = 1; j <= m; j ++) {
    			sum[i][j] = sum[i][j - 1] + a[i][j];
    		}
    	}
    	
    	for (int j = 1; j <= m; j ++) {
    		mx[0][j] = 0;
    		for (int i = 1; i <= n; i ++) {
    			mx[i][j] = max(mx[i - 1][j], a[i][j]);
    		}
    	}
    	
    	int ans = 0;
    	for (int j = 1; j + K - 1 <= m; j ++) {
    		int l = 1, r = n, p = 1;
    		int mid;
    		while (l <= r) {
    			mid = (l + r) >> 1;
    			if (check(mid, j)) {
    				l = mid + 1;
    				p = mid;
    			}
    			else {
    				r = mid - 1;
    			}
    		}
    		
    		for (int i = 1; i <= p; i ++) {
    			if (sum[i][j + K - 1] - sum[i][j - 1] == 0) {
    				ans ++;
    			}
    		}
    	}
    	
    	cout << ans << "\n";
    	
    	return 0;
    } 
    
    

    信息

    ID
    12643
    时间
    1500ms
    内存
    512MiB
    难度
    7
    标签
    递交数
    44
    已通过
    11
    上传者