当前位置:   article > 正文

P8783 [蓝桥杯 2022 省 B] 统计子矩阵_洛谷p8783思路

洛谷p8783思路

题目链接:[蓝桥杯 2022 省 B] 统计子矩阵 - 洛谷

解法一:暴力差分

代码:

  1. #include<iostream>
  2. using namespace std;
  3. const int N = 505;
  4. int a[N][N];
  5. int n,m,k;
  6. int cnt;
  7. int main()
  8. {
  9. cin>>n>>m>>k;
  10. for(int i=1;i<=n;++i)
  11. {
  12. for(int j=1;j<=m;++j)
  13. {
  14. cin>>a[i][j];
  15. a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
  16. }
  17. }
  18. for(int i=1;i<=n;++i)
  19. {
  20. for(int j=1;j<=m;++j)
  21. {
  22. big=false;
  23. for(int ii=i;ii<=n;++ii)
  24. {
  25. for(int jj=j;jj<=m;++jj)
  26. {
  27. if(a[ii][jj]-a[ii][j-1]-a[i-1][jj]+a[i-1][j-1]<=k) cnt++;
  28. else break;
  29. }
  30. }
  31. }
  32. }
  33. cout<<cnt<<endl;
  34. return 0;
  35. }

解法二:差分+双指针

思路:

先确定上下边界x,y,再确定左右边界l,r,在确定lr时,可以用双指针法

若区间[l , r]符合条件,那么他的子区间也符合条件,符合的区间数为 r-l+1 个

若 [l , r] 不符合条件,那么[l , r + k ]一定不符合条件,进行l++再判断

这样只需O(n)时间复杂度就可确定处lr边界。

代码:

  1. #include<iostream>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 505;
  5. ll a[N][N];
  6. ll tmp[N];
  7. ll n,m,k;
  8. ll cnt;
  9. int main()
  10. {
  11. cin>>n>>m>>k;
  12. for(int i=1;i<=n;++i)
  13. {
  14. for(int j=1;j<=m;++j)
  15. {
  16. scanf("%d",&a[i][j]);
  17. a[i][j]+=a[i][j-1];
  18. }
  19. }
  20. for(int x=1;x<=m;x++)
  21. {
  22. for(int y=x;y<=m;++y)
  23. {
  24. for(int i=1;i<=n;++i) tmp[i]=a[i][y]-a[i][x-1];
  25. for(int i=1;i<=n;++i) tmp[i]+=tmp[i-1];
  26. int l=1,r=1;
  27. while(r<=n&&l<=n)
  28. {
  29. if(tmp[r]-tmp[l-1]<=k) cnt+=(r-l+1),r++;
  30. else l++;
  31. }
  32. }
  33. }
  34. cout<<cnt<<endl;
  35. return 0;
  36. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/374343
推荐阅读
  

闽ICP备14008679号