给定小明的城堡图(小明的城堡并不是平面的,而是立体的)
请问,水的高度依次为 1,2,3,....,H时,有多少块积木要被水淹。
对于所有评测用例,(1<=n,m<=1000,1<=H<=100000),积木层数不超过(10^9)
思路
27/30做法:优化暴力即不去将枚举H的放在最外层循环,而是枚举h的在最内层,然后结束条件为min(g[i][j], h),这样可提早结束循环;
29/30做法:将二维网格转为一维,然后降序排序,对于每一个高度h,都从后往前找≥h的积木高度的方格个数,累加到s中
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1005*1005];
int main() {
int p=0; scanf("%d%d", &n,&m);
for (int i=0; i<n; i++)
for (int j=0; j<m; j++)
scanf("%d", &a[p++]);
int h, N=n*m, H, s=0; cin>>H;
sort(a,a+p,[&](int a, int b) {return b>a;});
for (int h=1; h<=H; h++) {
int i=p-1;
while (i>=0 && a[i]>=h) i--;
s+=p-i-1;
printf("%d
", s);
}
return 0;
}
30/30的做法是:升序排序数组a,这样就不用每次都从p-1开始枚举
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,a[1005*1005];
int main() {
int p=0; scanf("%d%d", &n,&m);
for (int i=0; i<n; i++)
for (int j=0; j<m; j++)
scanf("%d", &a[p++]);
ll h, N=n*m, H, i=0, last=0; cin>>H;
sort(a,a+p);
for (ll h=1; h<=H; h++) {
while (i<p && a[i]<h) i++;
last+=N-i; //筛选出已经淹没过的积木的个数i,N-i就是当前高度h可淹没的积木个数
printf("%lld
", last);
}
return 0;
}