1. 程式人生 > >ACM-ICPC 2018 南京賽區網路預賽 B. The writing on the wall

ACM-ICPC 2018 南京賽區網路預賽 B. The writing on the wall

題意:求一個n*m的矩形中有多少個不含黑塊的子矩形

題解:我們可以考慮一個矩形的子矩形的演算法,考慮一個子矩形的寬為w高為h,那麼含有nh)(mw)個這樣的子矩形,然後我們看一下有黑色方塊的矩形怎麼尋找他的子矩形,首先我們先考慮當前列最大的高度為多少(這裡我們設為h)在以當前點為右下角點的子矩形中有k=1jhk個,考慮到m比較小,我們可以遍歷所有的點讓他為右下點,然後暴力計算所有的子矩形即可

AC程式碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long
ll; #define met(a, b) memset(a, b, sizeof(a)) #define rep(i, a, b) for(int i = a; i <= b; i++) #define per(i, a, b) for(int i = a; i >= b; i--) #define pb push_back #define eb emplace_back #define mpi pair<int, int> #define fi first #define se second const int maxn = 2e5 + 10; const int inf = 0x3f3f3f3f
; int n, m, k, u, v, T, x, y; int up[maxn], a[maxn][120]; int main() { scanf("%d", &T); int cas = 1; while(T--) { met(up, 0); met(a, 0); ll ans = 0; scanf("%d%d%d", &n, &m, &k); rep(i, 1, k) scanf("%d%d", &x, &y), a[x][y] = 1; rep(i, 1
, n) { rep(j, 1, m) { if(a[i][j]) { up[j] = i; } } rep(j, 1, m) { ll MAX = 0; per(k, j, 1) { MAX = max(MAX, (ll)up[k]); ans += i - MAX; } } } printf("Case #%d: %lld\n", cas++, ans); } return 0; }