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,让你输出一个字符串。必须满足以下条件:
1.字符串的长度为n。
2.这个字符串只包含小写字母。
3.字符串中长度大于等于4的子串最多只能出现一次。
如果无解输出Impossible。

题目分析:
这题我们就是提出猜想过掉的。。
因为大于等于4的子串只能出现一次,所以想到串最长只会达到26*26*26*26+3 = 456979的长度。
一开始是想到了AC自动机,想在AC自动机上每走三个结点就回到根。。可是这根本做不到= =于是又诞生了另一种奇葩的方法——每增加一个字母时从a~z for一遍,看这个字母会不会和前三个字母构成的子串在之前的串中已经出现,如果未出现过,那么这个位置上就决定是这个字母了,然后下个位置直接从接下去的字母中选取;如果已经出现相同子串则枚举下个字母,如果一直到z还是不能添加一个字母到本位置但是这次a~z中已经有至少一个添加到之前的位置上时,重头再for,否则结束循环(因为已经枚举完所有的26个字母且都已经与前面三个字母构成的子串出现过了)。一开始我们设的aaa作为起始串,然后输出最后得到的串的长度达到了456954!无限接近,然后输出还没有添加到串中的字母一看,竟然除了a,所有四个相同字母如bbbb,cccc等都没有添加进去。。。然后就机智的将它们全部放到前面去,再次输出一看,最长串长度正好456979!问题解决。(至此我也明白了四个字母的子串只出现一次的主串长度最长能达到(26 ^ 4) + 3 )

PS:可以大胆的猜想,可以有x个不同字符的长度大于等于m(m <= x)的子串最多只能出现一次的主串的最长长度可以达到(x ^ m) + m - 1!证明留待后人。
*/

#include<stdio.h>
#include<string.h>
#include<string>
int  N=26*26*26*26+3;
char s[500010] ="aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz";
int vis[26][26][26][26];
void init()
{
    memset(vis,0,sizeof(vis));
    int len=26*4;
    int flag=1;
    for(int i=3;i<len;i++)
    {
        vis[s[i-3]-‘a‘][s[i-2]-‘a‘][s[i-1]-‘a‘][s[i]-‘a‘]=1;
    }
    while(flag)
    {
        flag=0;
        for(int i=0;i<26;i++)
        {
            if(!vis[s[len-3]-‘a‘][s[len-2]-‘a‘][s[len-1]-‘a‘][i])
            {
                s[len]=i+‘a‘;
                vis[s[len-3]-‘a‘][s[len-2]-‘a‘][s[len-1]-‘a‘][i]=1;
                len++;
                flag=1;
            }
        }
    }
}
int main()
{
    int n,len;
     init();

    while(~scanf("%d",&n))
    {
        if(n>N)printf("Impossible");
        else
        {
            for(int i=0;i<n;i++)
                printf("%c",s[i]);
        }
        puts("");
    }
    return 0;
}

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

时间: 2024-10-14 06:16:45

hdu 4850 Wow! Such String!(字符串处理,yy)的相关文章

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!

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

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! 构造 或 欧拉路径并改写成非递归版本

题目链接: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

HDU 3973 AC&#39;s String 字符串哈希

HDU 3973 通过哈希函数将一个字符串转化为一个整数,通过特定的方式可以使得这个哈希值几乎没有冲突(这就是关键之处,几乎没有视为没有= =!, 其实也可以考虑实现哈希冲突时的处理,只是这道题没必要而已),然后使用线段树维护修改后的哈希值. 因为输入的字符串只有26个,考虑使用一个大于等于26的素数p作为进制,然后将原串转化为一个p进制的数mod 2^63(也相当于自然溢出),然后这个数存入map中,然后使用线段树维护长串区间的哈希值,hash[l, r]表示将区间[l, r]的字符串转化为p

HDU 5842 Lweb and String(Lweb与字符串)

HDU 5842 Lweb and String(Lweb与字符串) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)   Problem Description - 题目描述 Lweb has a string S. Oneday, he decided to transform this string to a new sequence. You need help him

HDU 4893 Wow! Such Sequence! 水线段树

思路: 线段树走起.. 写完这题就退役T^T 单点更新的时候直接找到这个点的最近fib,然后维护当前和 和 fib的和 #include<stdio.h> #include<string.h> #include<iostream> #include<math.h> #include<algorithm> #include<queue> #include<map> #include<set> #include&l