HDU_4850_Wow! Such String!(构造)

来源:互联网 发布:中国少儿编程培训市场 编辑:程序博客网 时间:2024/06/14 03:53

题型:构造


题意:用26个小写字母组成长度为n的字符串,使得任意长度为4的子串不会是4个相同的字母。


分析:

       由于N范围为5*10^5,所以可以先预处理出最长的答案,然后短的直接从0开始取,长的输出Impossible。

       开标记数组vis[26][26][26][26],首先将aaaa~zzzz存在数组中,用vis数组标记存在过的4长度子串。

       然后在字符串尾部一个一个的加字母,并检测当前末尾4长度子串是否满足题意,若26个字母都无法加入的时候,字符串就预处理出来了。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<queue>#include<algorithm>#define MAXN 512345#define mt(a,b) memset(a,b,sizeof(a))using namespace std;bool vis[30][30][30][30];int ts[MAXN];int len;void init() {    mt(vis,false);    len = 0;    for(int j=0; j<26; j++) {        ts[len] = j;        ts[len+1] = j;        ts[len+2] = j;        ts[len+3] = j;        len += 4;    }    for(int i=0; i<len-3; i++) {        vis[ts[i]][ts[i+1]][ts[i+2]][ts[i+3]] = true;    }//    for(int i=0;i<len;i++){//        printf("%c",ts[i]+'a');//    }//    puts("");    while(len<MAXN) {        int num = 0;        for(int i=0; i<26; i++) {            if(!vis[ts[len-3]][ts[len-2]][ts[len-1]][i]) {                vis[ts[len-3]][ts[len-2]][ts[len-1]][i] = true;                ts[len] = i;                len++;            } else {                num++;            }        }        if(num == 26) break;    }//    cout<<"**********"<<endl;}int main() {    init();    int n;    while(~scanf("%d",&n)) {        if(n > len) {            puts("Impossible");        } else {            for(int i=0; i<n; i++) {                printf("%c",ts[i]+'a');            }            puts("");        }    }    return 0;}


0 0