zoukankan      html  css  js  c++  java
  • hdu-2795(线段树的简单应用)

    题目链接:传送门

    参考文章:https://blog.csdn.net/qiqi_skystar/article/details/50299743

    题意:给出一个高h,宽w的方形画板,有高位1宽为wi的单元,用这些单元去覆盖这个画板,每次求出单元在第几行,

    从画板的最顶部边开始,顶部不行就最左边,如果都不行,就输出-1.

    思路:

    总共n次,所以高度大于n也就没有意义了(题中的h范围很大,一开始我还想用离散化,后来发现是吓唬人的)

    每一行都要可以视为一个单元,所以就是求出这些行中的最大值,比较最大值与即将减去的值的大小,然后查找第一个符合条件的

    值的位置。因为要记录位置,所以最好用结构体来做比较方便。

    (我还是对线段树不太懂,一变形式就不知道了)

    (要先占据左边的所以cur[x*2].data先比较,表示向左比较,其次再向右比较。)

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn = 200100;
    struct Node{
        int Max,l,r;
    }cur[maxn<<2];
    int h,w,n;
    void pushup(int x)
    {
        cur[x].Max=cur[x*2].Max>cur[x*2+1].Max?cur[x*2].Max:cur[x*2+1].Max;
    }
    void build(int x,int l,int r)
    {
        cur[x].l=l;cur[x].r=r;cur[x].Max=w;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(x*2,l,mid);
        build(x*2+1,mid+1,r);
    }
    void update(int x,int Item)
    {
        if(cur[x].l==cur[x].r)
        {
            printf("%d
    ",cur[x].l);
            cur[x].Max-=Item;
            return ;
        }
        if(cur[x*2].Max>=Item) update(x*2,Item);
        else update(x*2+1,Item);
        pushup(x);
    }
    int main(void)
    {
        int x,i;
        while(~scanf("%d%d%d",&h,&w,&n))
        {
            if(h>n) h=n;
            build(1,1,h);
            for(i=1;i<=n;i++)
            {
                scanf("%d",&x);
                if(cur[1].Max>=x) update(1,x);
                else printf("-1
    ");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ES6入门之Promise对象
    Iterator和ListIterator区别
    try_catch_return
    T-SQL查询进阶--详解公用表表达式(CTE)
    Node.js安装及环境配置之Windows篇
    Java中Lambda表达式的使用
    windows下redis 开机自启动
    IDEA快捷键(修改成eclipse版)+Templates
    oracle赋予一个用户具有查询另一个用户所有表数据
    sql触发器
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10145868.html
Copyright © 2011-2022 走看看