程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU2795 billboard[轉化為線段樹。]

HDU2795 billboard[轉化為線段樹。]

編輯:C++入門知識

題意:h*w的木板,放進一些1*L的物品,求每次放空間能容納且最上邊的位子
思路:每次找到最大值的位子,然後減去L
線段樹功能:query:區間求最大值的位子(直接把update的操作在query裡做了)

 

 

技巧挺好,一開始自己思路建個超大二維數組,顯然內存不夠。

然後。  線段樹的話其實就是深搜,if(l==r) 返回的肯定是最左邊的結點,哈~

判斷的時候直接用Max[1]與p比較就能判斷是否輸出-1,贊一個!!

 

#include <iostream>   
#include <cstdio>   
#include <cmath>   
#include <cstring>   
#include <algorithm>   
using namespace std;  
  
#define lson rt<<1,l,m   
#define rson rt<<1|1,m+1,r   
  
int h,w,n;  
  
const int maxn=200005;// 是200000還是20000要搞清楚   
int Max[maxn<<2];     //開maxn的多少倍結合最底層的結點數加以注意   
  
void Pushup(int rt)  
{  
    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);  
}  
void build(int rt,int l,int r)  
{  
    Max[rt]=w;  
    if(l==r) return;  
    int m=(l+r)>>1;  
    build(lson);  
    build(rson);  
}  
int query(int p,int rt,int l,int r)//技巧5 . update放在query裡面了   
{  
    if(l==r)  
    {  
        Max[rt]-=p;  
        return l;// 2. 返回行數   
    }  
  
    int m=(l+r)>>1;  
    int ret;  
    ret=(Max[rt<<1]>=p)?query(p,lson):query(p,rson);// 技巧1.這地方深搜返回最左邊的結點即符合的。   
    Pushup(rt);// 技巧4 . 自己寫這個地方有可能會忘   
    return ret;  
}  
  
int main()  
{  
    while(scanf("%d%d%d",&h,&w,&n)!=EOF)  
    {  
        if(h>n) {h=n;}  
        build(1,1,h);  
  
        int p;  
        for(int i=1;i<=n;i++)  
        {  
            scanf("%d",&p);  
            if(Max[1]<p) printf("-1\n"); // 技巧3.Max[1]最根結點一定是最大值   
            else  
            {  
                int ans=query(p,1,1,h);  
                printf("%d\n",ans);  
            }  
        }  
    }  
    return 0;  
}  

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r

int h,w,n;

const int maxn=200005;// 是200000還是20000要搞清楚
int Max[maxn<<2];     //開maxn的多少倍結合最底層的結點數加以注意

void Pushup(int rt)
{
    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void build(int rt,int l,int r)
{
    Max[rt]=w;
    if(l==r) return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
int query(int p,int rt,int l,int r)//技巧5 . update放在query裡面了
{
    if(l==r)
    {
        Max[rt]-=p;
        return l;// 2. 返回行數
    }

    int m=(l+r)>>1;
    int ret;
    ret=(Max[rt<<1]>=p)?query(p,lson):query(p,rson);// 技巧1.這地方深搜返回最左邊的結點即符合的。
    Pushup(rt);// 技巧4 . 自己寫這個地方有可能會忘
    return ret;
}

int main()
{
    while(scanf("%d%d%d",&h,&w,&n)!=EOF)
    {
        if(h>n) {h=n;}
        build(1,1,h);

        int p;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&p);
            if(Max[1]<p) printf("-1\n"); // 技巧3.Max[1]最根結點一定是最大值
            else
            {
                int ans=query(p,1,1,h);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved