1. 程式人生 > >hdu 4850 字串構造---歐拉回路構造序列 遞迴+非遞迴實現

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\n",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('\n');
        }
    }
    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\n",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('\n');
        }
    }
    return 0;
}


相關推薦

hdu 4850 字串構造---構造序列 +實現

http://acm.hdu.edu.cn/showproblem.php?pid=4850 題意:構造長度為n的字元序列,使得>=4的子串只出現一次 其實最長只能構造出來26^4+4-1= 456979 的序列,大於該數的都是不可能的。構造方法,就是那種歐拉回路的序

HDU-3018-Ant Trip-+並查集

for its tin bits ems log set https 回路 Ant Trip 這道題一開始覺得是並查集,穩了;wa 才想起來有兩個重要條件 1、完全獨立的點不算; 2、把點連起來的邊(路)不能重復走:就是要判斷歐拉回路,即每個點的度數是不是偶數; 遍歷每個

hdu 2894 DeBruijin (

原創部落格 :https://blog.csdn.net/a709743744/article/details/51457790 題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=2894 第一問的答案毫無疑問是2^n 第二問的答

CF527E Data Center Drama(構造+

題目連結 大意: 給你一個無向圖。 要求加最少的邊,然後給這些無向圖的邊定向,使得每一個點的出入度都是偶數。 輸出定向後的邊數和邊集。 n<=10^5 m<=2*10^5 很巧妙的構造題…… 可以發現答案的下界是\(度數為奇數的點個數m + 度數為奇數的點個數/

[ 構造 || 網路流] Codeforces 723E #375 (Div. 2) E. One-Way Reform

通過歐拉回路構造  稱度為偶數的點為偶點 度為奇數為奇點 偶點可以滿足條件 而奇點不能 肯定可以通過只加奇點之間的邊使得存在歐拉回路 然後求歐拉回路 把加的邊刪去 對偶點無影響 那麼就能使所有偶點滿足

HDU 4850 Wow! Such String!

題目大意: 就是現在對於每一次給出的N <= 50W, 構造一個長度為N的串只包含小寫字母且每一個長度>=4的子串都只出現一次 如果不可能就輸出Impossible 大致思路: 首先考慮到如果長度為l + 1的串出現了兩次那麼長度為l的串一定也出現了兩次 所以

hdu 1956 (網絡流解決

www 起點到終點 更改 什麽 tps 網絡流 個性 http 混合圖 題目連接:https://vjudge.net/problem/HDU-1956 題意:給定一些點和一些邊,有些邊是有向的,,有些邊是無向的,求是否存在歐拉回路。 題解:想不到的網絡流。 混合圖:即

HDU 3018 Ant Trip (並查集求連通塊數+)

http 道路 遇到 連通塊 ems ble define ant trip 註意 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3018 題目大意:有n個點,m條邊,人們希望走完所有的路,且每條道路只能走一遍。至少要將人們

[agc018f]Two Trees——神仙構造題+or黑白染色 dalaos' blogs Some Links

題目大意: 給定兩顆帶了標號的有根樹,大小都是n,現在讓你對每一個點賦一個權值,使得每一個點的子樹和為-1或1。 思路: 首先我們可以算出每一個點的權值的奇偶性,一個點如果在兩顆樹中奇偶性不一樣一定無解,反之一定有解。 考慮怎麼構造,對於一個偶點,我們直接賦為0,對於奇點我們

hdu-1116(+並查集)

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1116 思路:將字串的頭元素和尾元素視為圖的x,y節點,然後合併x,y。 如果這個圖不連通,則門不能開啟,如果路徑是歐拉回路或者尤拉通路,則門可以開啟。 #include<iostream>

HDU - 1878【模板】

歐拉回路是指不令筆離開紙面,可畫過圖中每條邊僅一次,且可以回到起點的一條迴路。現給定一個圖,問是否存在歐拉回路? Input 測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是節點數N ( 1 < N < 1000 )和邊數M;隨後的M行對應M條邊,每行給出一對正整數,

HDU-3018 Ant Trip(

1 #include <bits/stdc++.h> 2 #define _for(i,a,b) for(int i = (a);i < (b);i ++) 3 using namespace std; 4 5 const int MAXV = 100003;

HDU-1878-(並查集)

歐拉回路是指不令筆離開紙面,可畫過圖中每條邊僅一次,且可以回到起點的一條迴路。現給定一個圖,問是否存在歐拉回路? Input 測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是節點數N ( 1 < N < 1000 )和邊數M;隨後的M行對應M條邊,每行給出一對

HDU-1116-Play on Words (並查集 +

原題連結: http://acm.hdu.edu.cn/showproblem.php?pid=1116 Some of the secret doors contain a very interesting word puzzle. The team of archaeologists

[JZOJ5959] 世界線修理 [AtCoder Grand Contest 018F](agc018F) Two Trees【圖論】【構造】【

原題連結:https://agc018.contest.atcoder.jp/tasks/agc018_f Description 給定兩棵都是N個節點的有根樹A,B,節點均從1~N標號。 我們需要給每個標號定一個權值,使在兩棵樹上均滿足任意節點子樹權值和為1或-1 輸出

HDU

Ant Trip Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2873    Accepted Submis

HDU 1878

題意: 歐拉回路的判斷條件, 一、無向圖 每個頂點的度數都是偶數,則存在歐拉回路。 二、有向圖(所有邊都是單向的) 每個節頂點的入度都等於出度,則存在歐拉回路。 以

HDU NO.1878 (鄰接矩陣,判斷的條件)

題意:(中文略) 思路: 存在歐拉回路的條件:所有頂點的度為偶數,並且圖是聯通的(每個點都可以遍歷) 這一類問題利用鄰接矩陣比較方便。 原題描述: Description 歐拉回路是指不令筆離

HDU:1878 (並查集+

1 0 題義就是在給定的圖中判定是否存在歐拉回路。 圖G的一個迴路,若它恰通過G中每條邊一次,則稱該回路為尤拉(Euler)迴路。 具有歐拉回路的圖稱為尤拉圖(簡稱E圖)。 這裡總結下各種圖的判定的方法: 1.無向圖中:所給定的圖為連通圖,且所有節點的度為偶數; 2.有向圖中:所給定的圖

hdu (判斷)

通過圖中所有邊1次且僅1次行遍所有頂點的通路稱作尤拉通路。 通過圖中所有邊1次且僅1次行遍所有頂點的迴路稱作歐拉回路。 具有歐拉回路的圖稱為尤拉圖。 具有尤拉通路而無歐拉回路的圖成為半尤拉圖。 無向圖: G是尤拉圖當且僅當G是是連通圖且沒有奇度頂點 G是半尤拉圖當且僅當G是