1. 程式人生 > >poj~2823(單調佇列入門)

poj~2823(單調佇列入門)

如果當初看單調佇列先從這題開始做的話,應該會快點理解吧。

題意就是求區間最值,這是單調佇列最簡單的應用。

題意:

給你n個數和區間長度k,求區間遍歷到第i個數時的最小和最大值,所以是n-k+1個值。

由於n的範圍是10^6,普通巢狀for肯定超時,這裡就用到了單調佇列。

單調佇列只需要遍歷一遍,雖然中間有出隊入隊的操作

具體的看程式碼和註釋吧:

#include <stdio.h>
#include <deque>

using namespace std;

int max_num[1000005],min_num[1000005],num[1000005];

int main()
{
    int n,k;
    while(scanf("%d %d",&n,&k)!=EOF)
    {
        deque<int > qmax,qmin;//單調佇列記錄下標
        for(int i=1;i<=k-1;i++) //先輸入前k-1個數,同時維護單調佇列
        {
            scanf("%d",&num[i]);
            while(!qmax.empty() && num[qmax.back()]<num[i]) qmax.pop_back();
            while(!qmin.empty() && num[qmin.back()]>num[i]) qmin.pop_back();
            qmax.push_back(i);
            qmin.push_back(i);
        }
        for(int i=k;i<=n;i++)   //從第k個數開始求區間最值
        {
            scanf("%d",&num[i]);
            while(!qmax.empty() && num[qmax.back()]<num[i]) qmax.pop_back();//同上,維護單調佇列
            while(!qmin.empty() && num[qmin.back()]>num[i]) qmin.pop_back();
            qmax.push_back(i);
            qmin.push_back(i);

            while(!qmax.empty() && i-qmax.front()>=k) qmax.pop_front(); //如果區間長度大於k,隊頭元素出隊
            while(!qmin.empty() && i-qmin.front()>=k) qmin.pop_front(); 

            max_num[i-k+1]=num[qmax.front()];   //記錄第i個最大值
            min_num[i-k+1]=num[qmin.front()];  //記錄第i個最小值
        }
        for(int i=1;i<=n-k;i++) //輸出
            printf("%d ",min_num[i]);
        printf("%d\n",min_num[n-k+1]);
        for(int i=1;i<=n-k;i++)
            printf("%d ",max_num[i]);
        printf("%d\n",max_num[n-k+1]);
    }
    return 0;
}


相關推薦

poj 2823 單調佇列入門題(內含手寫佇列的學習和模板)

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 39011 Accepted: 11554 Case Time Limit: 5000MS Descripti

POJ 2823 單調佇列入門

【解題報告】 這題是可以用優先佇列做的,這樣會簡單一些,不過考慮到是為了熟練的掌握斜率優化這一技巧,所以特意通過做這道題目來熟悉單調佇列的基本用法。因為考慮到單調佇列是從隊尾插入,訪問隊首元素。所以使用了雙端佇列這一STL。雖然要比手寫的模擬佇列要麻煩一些

poj~2823(單調佇列入門)

如果當初看單調佇列先從這題開始做的話,應該會快點理解吧。 題意就是求區間最值,這是單調佇列最簡單的應用。 題意: 給你n個數和區間長度k,求區間遍歷到第i個數時的最小和最大值,所以是n-k+1個值。

POj 2823 單調佇列 / 優先佇列

解法1:  單調佇列 所謂單調佇列就是一個單調遞增或遞減的佇列,並不是什麼神奇的東西。 單調佇列(就遞增來說)嚴格來說就是隊頭的原素是最大的,不斷從隊尾加原素,如果隊尾的原素比要加入來的原素大,就不斷退隊,就到隊尾的原素比要加入來的原素小或等於要加入來的原素。 這題只要分別

POJ 2823 單調佇列

// //poj2823(單調佇列) //給定一個大小已知的陣列以及一個大小已知的滑動視窗,視窗每個時刻向後移動一位,求出每個時刻視窗中數字的最大值和最小值。 //這個題是單調佇列的入門題。 //求最大值:建立一個單調遞減佇列,元素從左到右依次入隊,入隊之前必須從佇列尾部開

Sliding Window POJ - 2823 (單調佇列)

題目連結 這道題是一道非常經典的單調佇列題目. 單調佇列是一種單調遞增或單調遞減的佇列結構, 在C++STL中有priority_queue來實現了, 但較為麻煩只能對隊尾進行操作和訪問, 同時考慮到可能存在超時的因素, 所以在平常做題中我們一般都會選擇自己來實現單調佇列. 對於求類似

[NOIP模擬][POJ 2823][單調佇列]滑動的窗戶(Sliding Window)

題目描述: 題目連結: POJ 2823 http://poj.org/problem?id=2823 在一個包含 n 個元素的陣列上,有一個長度為 k 的窗戶在從左向右滑動。窗戶每滑動到一個位置,我們都可以看到 k 個元素在窗戶中。如下的例子所示,假設陣

poj 2823 單調佇列 deque寫法

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 46435 Accepted: 13417 Case Time Limit: 5000MS Description

POJ 2823】Sliding Window 【滑動視窗/單調佇列入門

題目大意 輸入一個長度為n(n≤≤106106)的數列,給定一個長度為k的視窗,讓這個視窗在數列上移動,求移動到每個位置視窗中包含數的最大值和最小值。即設序列為A1,A2,…,AnA1,A2,…,AnA1,A2,…,An,設f(i)=minAi−k+1Ai−k+

POJ 2823 Sliding Window(單調佇列入門題)

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 67218 Accepted: 19088 Case Time Limit: 5000MS Description An array of size 

單調佇列入門——POJ

單調佇列,顧名思義,維護的佇列中的資料是呈單調遞增或者單調遞減的,在維護單調佇列時,例如單調遞增佇列,當有新的資料入隊,則從隊尾開始,把所有大於該數的專案pop出佇列,保證了這個資料入隊後整個佇列依舊是單調遞增的,一般單調佇列的實現是用一個定長陣列和變數he

POJ2823——Sliding Window 單調佇列入門

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 40596 Accepted: 11992 Case Time Limit: 5000MS Description

POJ 2823 (從經典滑動視窗最大值問題入門單調佇列)

題目連結 題目大意 輸入一個長度為n(n≤106)的數列,給定一個長度為k的視窗,讓這個視窗在數列上移動,求移動到每個位置視窗中包含數的最大值和最小值。即設序列為A1,A2,…,An,設f(i)=min{Ai−k+1,Ai−k+2,…,Ak} ,g(

POJ - 2823 Sliding Window【單調佇列優化dp && c++快讀】

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 72718 &nb

poj 2823 Sliding Windows (單調佇列+輸入輸出掛)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 73426

POJ-2823-Sliding Window (單調佇列

原題連結: http://poj.org/problem?id=2823 An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the ver

單調佇列 POJ 2823 Sliding Window

  Sliding Window An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich is moving from

poj 2823 滑動視窗 單調佇列

Description An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the very left of the

POJ 2823 Sliding Window (單調佇列)

題目連結 Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the v

POJ 2823 Sliding Window(單調佇列||線段樹)

題意: 讓你不停的查詢區間長度為k的最小值和最大值 一開始用set模擬,發現常熟太大,T了,然後開始學單調佇列,看了一會兒還是好理解的,所以就寫了,發現G++會T,只能交C++,後來發現 有人線段樹也能過,於是就寫了一發,還真行,只不過就是吧