程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 2795 Billboard

HDU 2795 Billboard

編輯:C++入門知識

HDU 2795 Billboard


題目鏈接~~>

做題感悟:這題主要是想到以什麼為線段樹的葉子節點就好解決了。

解題思路:

讀完題,你會發現 h , w 的范圍都很大,如果把他們作為線段樹的葉子節點的話肯定是不行的,再一看 n ,貌似可以把他作為葉子節點,這樣的話每個葉子節點代表一行,在選擇的時候只要盡量選擇左子樹上的大於海報長度的就可以,這樣的話,區間保存的就是最大值,如果最大值都比當前的報紙小 必定不會繼續往下搜了。

代碼:

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std  ;
#define INT __int64
#define L(x)  (x * 2)
#define R(x)  (x * 2 + 1)
const int INF = 0x3f3f3f3f ;
const double esp = 0.0000000001 ;  
const double PI = acos(-1.0) ;
const int mod = 1e9 + 7 ;
const int MY = 50000 + 5 ;
const int MX = 200000 + 5 ;
int n ,h ,w ;
struct node
{
    int le ,rt ,c ;
}T[MX*4] ;
void build(int x ,int le ,int rt ,int w)
{
    T[x].le = le ; T[x].rt = rt ;
    T[x].c = w ;
    if(le == rt)  return ;
    int Mid = (le + rt)>>1 ;
    build(L(x) ,le ,Mid ,w) ;
    build(R(x) ,Mid+1 ,rt ,w) ;
    T[x].c = w ;
}
int Query(int x ,int w)  // 查詢同時修改最大值
{
    if(T[x].c < w)  return -1 ;
    if(T[x].le == T[x].rt)
    {
        T[x].c = T[x].c - w ;
        return T[x].le ;  // 返回找到的點
    }
    int mx = -1 ;
    if(T[L(x)].c >= w)
           mx = Query(L(x) ,w) ;
    else if(T[R(x)].c >= w)
           mx = Query(R(x) ,w) ;
    T[x].c = max(T[L(x)].c ,T[R(x)].c) ;
    return mx ;
}
int main()
{
    //freopen("input.txt" ,"r" ,stdin) ;
    int x ;
    while(~scanf("%d%d%d" ,&h ,&w ,&n))
    {
        int nx = n ;
        if(h < n)  n = h ;  // 可以優化一下
        build(1 ,1 ,n ,w) ;
        for(int i = 0 ;i < nx ; ++i)
        {
            scanf("%d" ,&x) ;
            printf("%d\n" ,Query(1 ,x)) ;
        }
    }
    return 0 ;
}



 

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