• hdu 4850 字符串构造---欧拉回路构造序列 递归+非递归实现


    http://acm.hdu.edu.cn/showproblem.php?

    pid=4850

    题意:构造长度为n的字符序列。使得>=4的子串仅仅出现一次

    事实上最长仅仅能构造出来26^4+4-1= 456979 的序列,大于该数的都是不可能的。构造方法。就是那种欧拉回路的序列,此题DFS会爆栈。手动扩展栈也能够AC......

    递归形式的開始WA了。没有细调就换非递归了,后来又想了想,尽管自己电脑上执行不了。可是先把长度按小的来。然后调试代码,然后在扩大,AC了,当时错在MOD,递归的MOD应该是26^4。而不是26^4+1,由于控制在0~(26^4-1)范围内,就是456976个数

    所以要变成非递归,我事实上不太理解非递归的,然后參考自己曾经做过的也是不太理解的这个代码http://blog.csdn.net/u011026968/article/details/38151303

    然后AC

    非递归版  46ms AC

    //#pragma comment(linker, "/STACK:102400000,102400000")
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <map>
    #include <set>
    #include <queue>
    using namespace std;
    
    #define ls(rt) rt*2
    #define rs(rt) rt*2+1
    #define ll long long
    #define ull unsigned long long
    #define rep(i,s,e) for(int i=s;i<e;i++)
    #define repe(i,s,e) for(int i=s;i<=e;i++)
    #define CL(a,b) memset(a,b,sizeof(a))
    #define IN(s) freopen(s,"r",stdin)
    #define OUT(s) freopen(s,"w",stdout)
    const ll ll_INF = ((ull)(-1))>>1;
    const double EPS = 1e-8;
    const int INF = 100000000;
    const int MAXN = 101;
    const int S = 500000;
    const int SIZE = 26;
    const int LEN = 456976+3;
    //const int MOD = 456976;
    const int MOD =17576;
    
    char str[LEN+10];
    char li[LEN*SIZE+10];
    int sta[LEN*SIZE+10];
    
    /*int dfs(int cnt, int s)
    {
        //printf("cnt=%d %d
    ",cnt,s);
        if(cnt == LEN)return 1;
        for(int i=0;i<SIZE;i++)
        {
            if(!vis[(s*SIZE+i)%MOD])///
            {
                vis[(s*SIZE+i)%MOD]=1;
                str[cnt]=i;
                if(dfs(cnt+1, (s*SIZE+i)%MOD))return 1;
                //vis[(s<<1)+i]=0;
            }
        }
        return 0;
    }*/
    int tp,ans;
    void sea(int v)
    {
        while(li[v]<SIZE)
        {
            int w=v*SIZE+li[v];
            li[v]++;
            sta[tp++]=w;
            v=w%MOD;
        }
    }
    void solve()
    {
        CL(str,0);
        CL(li,0);
        tp=0;
        int v;
        sea(0);
        str[0]='a';
        ans=1;
        while(tp)
        {
            v=sta[--tp];
            str[ans++]=v%SIZE+'a';
            v/=SIZE;
            sea(v);
        }
    }
    
    int main()
    {
        //OUT("hdu4850.txt");
        solve();
        int n;
        while(~scanf("%d",&n))
        {
            if(n>LEN)puts("Impossible");
            else
            {
                if(n<=4)
                {
                    for(int i=0;i<n;i++)
                        putchar('a');
                }
                else
                {
                    for(int i=1;i<4;i++)putchar('a');
                    int tt=ans;
                    n-=3;
                    while(tt>ans-n)putchar(str[--tt]);
                }
                putchar('
    ');
            }
        }
        return 0;
    }
    

    递归版 93ms AC

    #pragma comment(linker, "/STACK:102400000,102400000")
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <map>
    #include <set>
    #include <queue>
    using namespace std;
    
    #define ls(rt) rt*2
    #define rs(rt) rt*2+1
    #define ll long long
    #define ull unsigned long long
    #define rep(i,s,e) for(int i=s;i<e;i++)
    #define repe(i,s,e) for(int i=s;i<=e;i++)
    #define CL(a,b) memset(a,b,sizeof(a))
    #define IN(s) freopen(s,"r",stdin)
    #define OUT(s) freopen(s,"w",stdout)
    const ll ll_INF = ((ull)(-1))>>1;
    const double EPS = 1e-8;
    const int INF = 100000000;
    const int MAXN = 101;
    const int S = 500000;
    const int SIZE = 26;
    const int LEN = 456976+3;
    const int MOD = 456976;
    
    int str[LEN+10];
    int vis[LEN+10];
    
    int dfs(int cnt, int s)
    {
        //printf("cnt=%d %d
    ",cnt,s);
        if(cnt == LEN)return 1;
        for(int i=0;i<SIZE;i++)
        {
            if(!vis[(s*SIZE+i)%MOD])///
            {
                vis[(s*SIZE+i)%MOD]=1;
                str[cnt]=i;
                if(dfs(cnt+1, (s*SIZE+i)%MOD))return 1;
            }
        }
        return 0;
    }
    
    
    void init()
    {
        CL(str,0);
        CL(vis,0);
        vis[0]=1;
        dfs(4,0);
    }
    
    int main()
    {
        //OUT("hdu4850.txt");
        init();
        int n;
        while(~scanf("%d",&n))
        {
            if(n>LEN)puts("Impossible");
            else
            {
                for(int i=0;i<n;i++)
                    putchar(str[i]+'a');
                putchar('
    ');
            }
        }
        return 0;
    }
    


  • 相关阅读:
    UVA 10480 Sabotage (最大流最小割)
    bzoj2002 [Hnoi2010]Bounce 弹飞绵羊 (分块)
    poj3580 SuperMemo (Splay+区间内向一个方向移动)
    bzoj1500: [NOI2005]维修数列 (Splay+变态题)
    hdu3436 Queue-jumpers(Splay)
    hdu4710 Balls Rearrangement(数学公式+取模)
    hdu1890 Robotic Sort (splay+区间翻转单点更新)
    zoj2112 Dynamic Rankings (主席树 || 树套树)
    poj3581 Sequence (后缀数组)
    notepa++ Emmet的安装方法
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7087109.html
Copyright © 2020-2023  润新知