• 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;
    }
    
  • 相关阅读:
    select top 变量问题
    distinct top執行順序
    Subquery typo with using in(转)
    sql:查询课程号'0312091006'成绩排名第5到第10之间的学生学号
    case when then
    触发器
    索引
    管理事物处理
    053345
    053344
  • 原文地址:https://www.cnblogs.com/wdt1/p/13805671.html
Copyright © 2020-2023  润新知