Wow! Such String!

题目链接

  • 题意:

    给一个n,输出一个长度为n的字符串,使得串中任意相连四个字符组成的串不重复N (1 ≤ N ≤ 500000)

  • 分析:
const int MAXV = 18278;
const int MAXE = 475228;

struct Edge
{
    int from, to;
};

struct Direct_Euler
{
    int n, m;
    int out[MAXV];
    bool vis[MAXE];
    vector<int> G[MAXV];
    vector<Edge> edges;
    stack<int> sk;
    vector<int> ans;

    void init(int n)
    {
        this->n = n;
        edges.clear();
        REP(i, n)
        {
            out[i] = 0;
            G[i].clear();
        }
    }

    void addEdge(int a, int b)
    {
        edges.push_back((Edge) { a, b });
        m = edges.size();
        G[a].push_back(m - 1);
        out[a]++; out[b]--;
    }

    void dfs(int u, int ind)
    {
        REP(i, G[u].size())
        {
            int x = G[u][i];
            Edge& e = edges[x];
            if (!vis[x])
            {
                vis[x] = true;
                dfs(e.to, x);
            }
        }
        if (ind >= 0)
            sk.push(ind);
    }

    //返回1:欧拉回路  返回2:欧拉路经
    int solve(int s)
    {
        int cnt = 0;
        ans.clear();
        REP(i, n)
        {
            if (out[i] == 1)
            {
                if (++cnt > 1)
                {
                    return 0;
                }
                s = i;
            }
            else if (out[i] > 1 || out[i] < -1)
                return 0;
        }
        while (!sk.empty()) sk.pop();
        REP(i, m) vis[i] = false;
        dfs(s, -1);
        REP(i, m)
            if (!vis[i])
                return 0;
        while (!sk.empty())
        {
            ans.push_back(sk.top());
            sk.pop();
        }
        return cnt != 0 ? 1 : 2;
    }
} graph;
char x[456979], tot = 0;
int main()
{
    int size = 29 << 20; // 29MB
    char *p = (char*)malloc(size) + size;
    __asm__("movl %0, %%esp\n" :: "r"(p));

    graph.init(18278);
    REP(i, 26) REP(j, 26) REP(k, 26) REP(l, 26)
        graph.addEdge(i * 676 + j * 26 + k, j * 676 + k * 26 + l);
    graph.solve(0);
    vector<int>& ans = graph.ans;
    int tot = 0;

    int to = graph.edges[ans[0]].from;
    x[tot++] = to / 676 + 'a';
    to %= 676;
    x[tot++] = to / 26 + 'a';
    to %= 26;
    x[tot++] = to + 'a';
    REP(i, ans.size())
        x[tot++] = graph.edges[ans[i]].to % 26 + 'a';
    int n;
    while (~RI(n))
    {
        if (n > tot)
            puts("Impossible");
        else
        {
            REP(i, n)
                printf("%c", x[i]);
            puts("");
        }
    }
    return 0;
}

其实,如果没有想到是欧拉回路问题,暴力也是可以试试的,懊悔当时没写出来,祭奠一下。。

const int MAXN = 1000000;

bool vis[26][26][26][26];
int x[MAXN];
int tot;

int main()
{
    tot = 0;
    REP(i, 26)
    {
        x[tot + 3] = x[tot + 2] = x[tot + 1] = x[tot] = i;
        tot += 4;
    }
    FF(i, 3, tot)
        vis[x[i]][x[i - 1]][x[i - 2]][x[i - 3]] = 1;
    bool flag = true;
    while (flag)
    {
        flag = false;
        REP(i, 26)
        {
            if (!vis[i][x[tot - 1]][x[tot - 2]][x[tot - 3]])
            {
                vis[i][x[tot - 1]][x[tot - 2]][x[tot - 3]] = 1;
                x[tot++] = i;
                flag = true;
            }
        }
    }

    int n;
    while (~RI(n))
    {
        if (n > tot)
            puts("Impossible");
        else
        {
            REP(i, n)
                printf("%c", x[i] + 'a');
            puts("");
        }
    }
    return 0;
}

Wow! Such String!

时间: 2024-08-24 05:20:41

Wow! Such String!的相关文章

hdu 4850 Wow! Such String!

这是当时西安邀请赛的题目,也就是因为这道题,我们无缘银牌... 其实这道题的大致想法当时我想出来了,就是我是想找到一条通过所有顶点的通路,顶点是所有的长度是4的子串.但是当时没有尝试搜索,以为不会这么简单就找到那条路.但是现在明白了,对于所有顶点度数为偶数的图,一定可以找到这样一条路的. 下面是代码 #include <iostream> #include <cstdio> #include <cstring> using namespace std; const in

hdu 4850 Wow! Such String!(欧拉回路)

题目链接:hdu 4850 Wow! Such String! 题目大意:给定一个n,要求输出一个长度为n的字符串,并且不会有长度大于等于4的重复的子串,不能得到输出impossible. 解题思路:这题有一个误导性的地方,500000,其实是构造不到那么长的,我们考虑所有不相同并且长度为4的串,一共有s=264个,那么我们假设有一个很长的串,满足不会有长度大于等于4的重复的子串,那么以0,1,2,3...的位置为起始,长度为4的子串一定都是s中的某一个串,因为不重复,所以肯定只有264个位置做

HDU 4850 Wow! Such String!(欧拉道路)

HDU 4850 Wow! Such String! 题目链接 题意:求50W内的字符串,要求长度大于等于4的子串,只出现一次 思路:需要推理,考虑4个字母的字符串,一共有26^4种,这些由这些字符串,如果一个字符串末尾加上一个字符,可以变成另一个字符串的话,就当作这有一条边,每多一个字符多一个结点,那么对于这道题目,一共就能有26^4 + 3条边,在加上尾巴可以多放3个,一共是26^4+3个边,这些边全部连起来就是要的字符串,这样就可以知道每个节点会经过的次数为26,这样就只要考虑如何把这些节

hdu 4850 Wow! Such String!(字符串处理,yy)

题目 参考了博客http://blog.csdn.net/u013368721/article/details/37575165 //用visit[26][26][26][26]来判断新家新区的子母河前三个组合而成的4个字符的串是否和之前的重复. //再加上最初三个字符,所以,总共有26*26*26*26+3的长度. /* //以下复制自博客http://blog.csdn.net/u013368721/article/details/37575165 题目大意:给你一个整数n,让你输出一个字符

hdu 4850 Wow! Such String! 构造 欧拉回路

Wow! Such String! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 934    Accepted Submission(s): 318 Special Judge Problem Description Recently, doge starts to get interested in a strange probl

HDU-4850 Wow! Such String! (构造)

Problem Description Recently, doge starts to get interested in a strange problem: whether there exists a string A following all the rules below: 1.The length of the string A is N . 2.The string A contains only lowercase English alphabet letters. 3.Ea

hdu 4850 Wow! Such String! 构造 或 欧拉路径并改写成非递归版本

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4850 跟这道题也算是苦大仇深了... 题意:构造一个由26个小写字母组成的.无长度为4的重复子串的字符串(要求出能构造出的最大长度) 符合要求的长度为4的字符串有4^26个 容易猜最大长度是:4^26+3 = 456979 比赛的时候想法是要让各个字母出现得尽量“均匀” 用了一个cnt数组记录26个字母出现的次数 每次都选择出现次数最小的.不与前面重复的字母加上去 然而稍微写得有点歪,最后构造出了长

HDU 4850 Wow! Such String! 【欧拉回路】【一顿乱构造】

link: http://acm.hdu.edu.cn/showproblem.php?pid=4850 题解: 每个长度为3的字符串当一个节点,每个节点连出26条边,代表给长度为3的字符串吼添加'a'~'z' 那我们每条边经过一次,就能构造出长度为26^4 + 3的字符串! 我们从"aaa"表示的节点出发,注意到每个点出度为26,入度也为26. 所以,非"aaa"的节点,能进去就能离开.(因为这些点是:先入再出) "aaa"表示的节点,进入26

2014西安全国邀请赛

D - Wow! Such String!: 这道字符串题居然正解是欧拉图,我也是看醉了...欧拉图虽然学过,但可能理解得还不是很深,所以对这种题不敏感. 这道题解法是把每四个字符组成的字符串看成是一个点,每个点有26个入边和26个出边,可以证明这是一个欧拉图.然后遍历找一下欧拉图就行了. 不过...一开始我是自己建了个图...结果超内存...然后想打表...结果根本不让我交...实在无奈,改成了每个点自己找下一个点,不连边.(现在想想连边好像是没有必要的)另,看题的时候还是要仔细看题目要求,尽