• <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 - 1256 和 POJ百練 - 1833)

            題目1描述:
            輸入:一個(gè)序列s,該序列里面可能會(huì)有同樣的字符,不一定有序
            輸出:打亂輸入中的序列,可能產(chǎn)生的所有新的序列
            題目2描述:
            輸入:一個(gè)序列s,該序列里面可能會(huì)有同樣的字符,不一定有序 和 一個(gè)整數(shù)k
            輸出:該序列往后計(jì)算第k個(gè)序列,所有序列是以字典序排序的

            如果會(huì)有序搜索的童鞋自然而然能立刻做出來第一個(gè)題目,可是第二個(gè)題目在s較長的情況下,卻需要用模擬而不是搜索...
            大家都知道STL里面有個(gè)泛函模版, prev_permutation和next_permutation,用法也很簡單,實(shí)現(xiàn)的就是題目2的功能...
            但是算法最好得靠自己想出來,自己想出來的才是自己的,碰到新的問題才能產(chǎn)生思想的火花...

            廢話少說,題目1的解法就是深搜,不過需要加上一個(gè)bool數(shù)組標(biāo)記和一個(gè)函數(shù)確定不同字符之間的大小(有可能這個(gè)大小還不是Ascii碼就能決定的),
            大致描述下搜索過程,比如輸入序列是12345,那么我搜索的過程大致是第一層按順序選取1-5,進(jìn)入第二層的時(shí)候也是按順序選取1-5,
            以此類推,但是每一層里面都只能選前面的層次沒有選過的數(shù),而且因?yàn)橛兄貜?fù)字符,算法還必須保證每一層里面按順序選取的字符必須是升序的,
            熟悉順序搜索和回溯的同學(xué),很自然就會(huì)產(chǎn)生這樣的想法...
            POJ - 1256的代碼如下:
            #include <stdio.h>
            #include <string.h>
            #include <ctype.h>
            #include <stdlib.h>
            #include <algorithm>
            #define MAX (13 + 10)
            using namespace std;
            bool bUsed[MAX];
            char szAns[MAX];
            char szInput[MAX];
            bool CmpChar(char chOne, char chTwo)
            {
                if (abs(chOne - chTwo) != 'a' - 'A')
                {
                    return tolower(chOne) - tolower(chTwo) < 0;
                }
                return chOne - chTwo < 0;
            }
            bool Greater(char chOne, char chTwo)
            {
                if (abs(chOne - chTwo) != 'a' - 'A')
                {
                    return tolower(chOne) - tolower(chTwo) > 0;
                }
                return chOne - chTwo > 0;
            }
            void Gen(int nDepth, int nLen)
            {
                if (nDepth == nLen)
                {
                    szAns[nLen] = '\0';
                    printf("%s\n", szAns);
                    return;
                }
                
                char chLast = '\0';
                for (int i = 0; i < nLen; ++i)
                {
                    if (!bUsed[i] && Greater(szInput[i], chLast))
                    {
                        bUsed[i] = true;
                        szAns[nDepth] = szInput[i];
                        Gen(nDepth + 1, nLen);
                        bUsed[i] = false;
                        chLast = szInput[i];
                    }
                }
            }
            int main()
            {
                int nCases;
                
                scanf("%d", &nCases);
                while (nCases--)
                {
                    scanf("%s", szInput);
                    int nLen = strlen(szInput);
                    sort(szInput, szInput + nLen, CmpChar);
                    Gen(0, nLen);
                }
                
                return 0;
            }
            題目2的解法是模擬,功能類似與STL的那2個(gè)泛型模版函數(shù),算法的大致過程是想辦法從當(dāng)前序列進(jìn)入下一個(gè)剛好比其大或者剛好比其小的序列...很自然我們想到要把序列后面大的字符交和前面小的字符交換就會(huì)使序列變大,為了使其剛好變大,可以把交換后的字符從交換位置起至最后都排序一下,現(xiàn)在的問題是我們?nèi)绾芜x取2個(gè)字符交換...正確的想法是,我們從最后面開始往前面看,尋找一個(gè)最長的遞增序列,找到之后,我們只需要選取遞增序列前面的那個(gè)字符chBefore和遞增序列里面的一個(gè)最小的比chBefore大的字符交換即可...交換之后,將新的遞增序列排序一下即可...
            為什么這樣做了,因?yàn)閺暮笸翱吹倪f增序列,是不能交換2個(gè)字符讓當(dāng)前序列變大的,所以必須選取最長遞增序列前面的那個(gè)字符交換...

            POJ百練 - 1833 的代碼如下:
            #include <stdio.h>
            #include <string.h>
            #include <algorithm>
            #define MAX (1024 + 10)
            using namespace std;
            int nInput[MAX];
            void GetNext(int* nInput, int nLen)
            {
                int i = nLen - 2;
                while (i >= 0)
                {
                    if (nInput[i] >= nInput[i + 1])
                    {
                        --i;
                    }
                    else
                    {
                        int k = i + 1;
                        for (int j = nLen - 1; j > i; --j)
                        {
                            if (nInput[j] > nInput[i] && nInput[j] < nInput[k])
                            {
                                k = j;
                            }
                        }
                        swap(nInput[i], nInput[k]);
                        sort(nInput + i + 1, nInput + nLen);
                        return;
                    }
                }
                
                sort(nInput, nInput + nLen);
            }
            int main()
            {
                int nCases;
                scanf("%d", &nCases);
                while (nCases--)
                {
                    int nLen;
                    int nK;
                    scanf("%d%d", &nLen, &nK);
                    for (int i = 0; i < nLen; ++i)
                    {
                        scanf("%d", &nInput[i]);
                    }
                    for (int i = 0; i < nK; ++i)
                    {
                        GetNext(nInput, nLen);
                    }
                    for (int i = 0; i < nLen; ++i)
                    {
                        printf("%d%s", nInput[i], i == nLen - 1 ? "\n" : " ");
                    }
                }
                return 0;
            }

            posted on 2011-12-26 15:53 yx 閱讀(1510) 評論(0)  編輯 收藏 引用 所屬分類: 搜索模擬

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

            導(dǎo)航

            統(tǒng)計(jì)

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學(xué)

            網(wǎng)友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久嫩草影院免费看夜色| 久久久久无码精品国产| 麻豆国内精品久久久久久| 久久中文字幕精品| 久久婷婷色综合一区二区| 久久综合亚洲色HEZYO国产| 久久精品国产AV一区二区三区| 亚洲中文字幕无码久久2017 | 伊人久久大香线焦AV综合影院| 综合人妻久久一区二区精品| 亚洲嫩草影院久久精品| 国产精品久久久香蕉| 91麻精品国产91久久久久| 久久久久精品国产亚洲AV无码| 国产99精品久久| 国产aⅴ激情无码久久| 久久国产成人| 亚洲国产成人久久综合碰碰动漫3d| 久久久一本精品99久久精品88| 久久电影网一区| 久久亚洲AV成人出白浆无码国产| 久久久久国产视频电影| 久久成人精品视频| 99久久这里只有精品| 婷婷五月深深久久精品| 欧美日韩精品久久久久| 理论片午午伦夜理片久久| 久久男人AV资源网站| 国产成人久久精品二区三区| 久久99热狠狠色精品一区| 亚洲精品乱码久久久久久自慰 | 一本色道久久99一综合| 久久精品国产亚洲5555| 狠狠久久综合| 亚洲精品无码久久久久AV麻豆| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 亚洲人成网站999久久久综合| 国产女人aaa级久久久级| 精品久久久久久无码免费| 精品久久久无码中文字幕| 四虎国产永久免费久久|