• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            poj 2823 Sliding Window 單調(diào)隊(duì)列

               這道題的意思是給定一個(gè)長(zhǎng)N的整數(shù)序列,用一個(gè)大小為K的窗口從頭開(kāi)始覆蓋,問(wèn)第1-第N-K次窗口里面最大的數(shù)字和最小的數(shù)字。
               剛開(kāi)始還以為優(yōu)先級(jí)隊(duì)列可以做,發(fā)現(xiàn)無(wú)法刪除最前面的元素。估計(jì)用線段樹(shù)這個(gè)題也是可以解得。用這個(gè)題學(xué)了下單調(diào)隊(duì)列。
               
               單調(diào)隊(duì)列正如其名,是一個(gè)從小到大排序的隊(duì)列,而且能夠保證所有的元素入隊(duì)列一次出隊(duì)列一次,所以平攤到每個(gè)元素的復(fù)雜度
            就是O(1)。
               對(duì)于這個(gè)題單調(diào)隊(duì)列的使用。以序列1 3 -1 -3 5 3 6 7舉例。
               1)元素類(lèi)型:一個(gè)結(jié)構(gòu)體,包含數(shù)字大小和位置,比如(1,1),(3,2)。
               2)插入操作:從隊(duì)尾開(kāi)始查找,把隊(duì)尾小于待插入元素的元素全部刪除,再加入待插入的元素。這個(gè)操作最壞的
            情況下是O(n),但是我們采用聚集分析的方法,知道每個(gè)元素最多刪除一次,那么N個(gè)元素刪除N次,平攤到每一次
            操作的復(fù)雜度就是O(1)了。
               3)刪除隊(duì)首元素:比如本文給的那個(gè)題,窗口一直往后移動(dòng),每一次移動(dòng)都會(huì)刪除一個(gè)元素,所以很可能隊(duì)首會(huì)是要
            刪除的元素,那么每次移動(dòng)窗口的元素要進(jìn)行一次檢查,如果隊(duì)首元素失效的話,就刪掉隊(duì)首元素。

               代碼的實(shí)現(xiàn),我是包裝deque實(shí)現(xiàn)了一個(gè)模版類(lèi)。速度很不好,居然跑了11s多才過(guò),幸虧給了12s的時(shí)間,看status又500多ms
            就過(guò)了的。估計(jì)數(shù)組實(shí)現(xiàn)會(huì)快很多。

               代碼如下:
            #include <stdio.h>
            #include <deque>
            #include <algorithm>
            using namespace std;
            #define MAX_N (1000000 + 100)
            int nNum[MAX_N];
            int nN, nK;

            struct Small
            {
                int nValue;
                int nIndex;
                Small(int nV, int index):nValue(nV), nIndex(index) {}
                bool operator < (const Small& a) const
                {
                    return nValue < a.nValue;
                }
            };

            struct Big
            {
                int nValue;
                int nIndex;
                Big(int nV, int index):nValue(nV), nIndex(index) {}
                bool operator < (const Big& a) const
                {
                    return nValue > a.nValue;
                }
            };

            //單調(diào)隊(duì)列
            template <typename T> class Monoque
            {
                deque<T> dn;

            public:
                void Insert(T node)
                {
                    int nPos = dn.size() - 1;
                    while (nPos >=0 && node < dn[nPos])
                    {
                        --nPos;
                        dn.pop_back();
                    }
                    dn.push_back(node);
                }

                int Top()
                {
                    return dn.front().nValue;
                }

                void Del(int nBeg, int nEnd)
                {
                    if (dn.size() > 0)
                    {
                        if (dn.front().nIndex < nBeg || dn.front().nIndex > nEnd)
                        {
                            dn.pop_front();
                        }
                    }
                }
            };

            int main()
            {
                while (scanf("%d%d", &nN, &nK) == 2)
                {
                    int i;
                    for (i = 0; i < nN; ++i)
                    {
                        scanf("%d", &nNum[i]);
                    }
                    Monoque<Small> minQ;
                    Monoque<Big> maxQ;

                    for (i = 0; i < nK; ++i)
                    {
                        minQ.Insert(Small(nNum[i], i));
                    }

                    for (i = 0; i < nN - nK; ++i)
                    {
                        printf("%d ", minQ.Top());
                        minQ.Insert(Small(nNum[i + nK], i + nK));
                        minQ.Del(i + 1, i + nK);
                    }
                    printf("%d\n", minQ.Top());

                    for (i = 0; i < nK; ++i)
                    {
                        maxQ.Insert(Big(nNum[i], i));
                    }

                    for (i = 0; i < nN - nK; ++i)
                    {
                        printf("%d ", maxQ.Top());
                        maxQ.Insert(Big(nNum[i + nK], i + nK));
                        maxQ.Del(i + 1, i + nK);
                    }
                    printf("%d\n", maxQ.Top());
                }

                return 0;
            }

            posted on 2012-09-02 14:25 yx 閱讀(1688) 評(píng)論(2)  編輯 收藏 引用 所屬分類(lèi): 數(shù)據(jù)結(jié)構(gòu)

            評(píng)論

            # re: poj 2823 Sliding Window 單調(diào)隊(duì)列 2012-09-04 09:16 畢達(dá)哥拉斯半圓

            問(wèn)個(gè)問(wèn)題,如果窗口的長(zhǎng)度變的,復(fù)雜度該如何分析呢?  回復(fù)  更多評(píng)論   

            # re: poj 2823 Sliding Window 單調(diào)隊(duì)列 2012-09-04 16:48 遠(yuǎn)行

            @畢達(dá)哥拉斯半圓
            總的應(yīng)該還是O(n),還是用聚集分析的方法,所有元素就入一次隊(duì)列,
            最多出一次隊(duì)列,平攤到每個(gè)元素就是O(1)  回復(fù)  更多評(píng)論   

            <2012年9月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            導(dǎo)航

            統(tǒng)計(jì)

            公告

            常用鏈接

            留言簿(3)

            隨筆分類(lèi)

            隨筆檔案

            me

            好友

            同學(xué)

            網(wǎng)友

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            国产精品99久久不卡| 亚洲精品美女久久久久99小说| 婷婷久久五月天| 久久天天躁狠狠躁夜夜不卡| 久久久久久久97| 97r久久精品国产99国产精| 亚洲伊人久久大香线蕉苏妲己 | 色99久久久久高潮综合影院| 久久这里只有精品首页| 少妇人妻88久久中文字幕| 久久午夜电影网| yy6080久久| 国产激情久久久久影院老熟女| 精品久久久久久无码不卡| 久久国产一区二区| 色欲综合久久躁天天躁蜜桃| 日韩一区二区久久久久久| 亚洲AV成人无码久久精品老人 | 91精品国产综合久久香蕉 | 久久九九全国免费| 亚洲精品乱码久久久久久不卡| 久久精品国产久精国产思思| 伊人精品久久久久7777| 精品久久久久久久中文字幕 | 精品久久8x国产免费观看| 日本久久久久久久久久| 伊人久久精品线影院| 国产精品9999久久久久| 一本久道久久综合狠狠爱| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久久婷婷五月亚洲97号色 | 欧美日韩精品久久久久| 久久久久99精品成人片试看 | 久久99九九国产免费看小说| 国产精品美女久久久免费| 久久综合精品国产二区无码| 亚洲熟妇无码另类久久久| 一级a性色生活片久久无| 亚洲精品97久久中文字幕无码| 欧美性大战久久久久久| 欧美午夜A∨大片久久 |