zoukankan      html  css  js  c++  java
  • b_lq_小明的魔法(反向思维)

    给定小明的城堡图(小明的城堡并不是平面的,而是立体的)
    请问,水的高度依次为 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;
    }
    
  • 相关阅读:
    alpha版本冲刺总结
    近两天项目冲刺
    关于微软必应词典客户端 的案例分析
    第三次作业——结队编程
    hdu 1002 A + B Problem II(大数)
    ZOJ 3805 Machine(二叉树,递归)
    hdu 4704 sum(费马小定理+快速幂)
    欧拉图
    hdu 1116 Play on Words(欧拉通路)
    前50个斐波那契数
  • 原文地址:https://www.cnblogs.com/wdt1/p/13805671.html
Copyright © 2011-2022 走看看