题目链接:https://nanti.jisuanke.com/t/A1948
题目大意:给你一个n * m的矩阵。有k个黑块。问有多少个不包含黑块的矩阵。
思路:时间给你2秒。我们考虑n * m * m的写法。枚举每个点作为右下角。再枚举矩阵的宽。
如图:以右下角0号点为矩阵的右下角的矩阵个数。枚举x。为矩阵的左边界。如图0和0-4都会产生一个矩形。ans+=H
枚举x到前一个位置。如图0和1-5都会产生一个矩形。ans+=H
枚举x到前一个位置。如图0和1-3都会产生一个矩形。ans+=H
枚举x到前一个位置。如图0和1-3都会产生一个矩形。ans+=H
枚举x到前一个位置。如图0和1-2都会产生一个矩形。ans+=H
枚举x到前一个位置。如图0和1-2都会产生一个矩形。ans+=H
H[i]=第i列离垂直方向上第一个黑色块的距离。我们边枚举边计算H[i]就可以了。如果(x, y)是黑块.mx[y]=x。H[i]=i-mx[i]+1。
#include <bits/stdc++.h> #define LL long long using namespace std; int hs[100005][105], mx[105]; vector<int> v; int main(){ int T, cas=1; scanf("%d", &T); while(T--){ memset(mx, 0, sizeof(mx)); int n, m, k, x, y; scanf("%d%d%d", &n, &m, &k); for(int i=1; i<=k; i++){ scanf("%d%d", &x, &y); hs[x][y]=1; v.push_back(x); v.push_back(y); } LL ans=0; for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++){ if(hs[i][j]){ mx[j]=i; } } for(int j=1; j<=m; j++){ int h=i; for(int k=j; k>0; k--){ h=min(h, i-mx[k]); ans+=h; } } } for(int i=0; i<v.size(); i+=2){ hs[v[i]][v[i+1]]=0; } printf("Case #%d: %lld\n",cas++, ans); } return 0; }