HDU4850 构造一个长度为n的串,要求任意长度为4的子串不相同

n《=50W。(使用26个字母)

构造方法:26个,最多构造出26^4种不同的串,长度最长是26^4+3,大于是输出“impossble”,用四维数组判重。每次向前构造一位(先从上一位字符后一个开始),这样,可以构造出26^4-25种,打印出来发现(bbbb~zzzz),构造不出来,于是,学习了他人方法,把这些放在最前面,再重复上述方法构造即可(以后都可以用这种向前推一法构造)。

PS:从中额外学得:若用string 的s=s+char,拼接,速度很慢,用char s[],然后s[size++]=char,快得多。输出有点意思,直接输出n个即可,末地址起。

#include<iostream>  //46MS
#include<string>
#include<cstdio>
using namespace std;
int mark[26][26][26][26];
char s[480000];
int size=0;
int main()
{
    int n;
     for(int i=0;i<26;i++)
    {
                s[size++]=char(i+'a');
                s[size++]=char(i+'a');
                s[size++]=char(i+'a');
                s[size++]=char(i+'a');
    }
    for(int i=0;i<size-3;i++)
        mark[s[i]-'a'][s[i+1]-'a'][s[i+2]-'a'][s[i+3]-'a']=1;
    int t1=25,t2=25,t3=25;
            for(int i=104;i<=456979;i++)
            {
                int count1=0;
                for(int j=t3+1;count1<2;j++)
                {
                     if(j==26)
                    {
                        j=0;
                        count1++;
                    }
                    if(mark[t1][t2][t3][j]==0)
                    {
                        mark[t1][t2][t3][j]=1;
                        char temp=j+'a';
                        s[size++]=temp;
                        t1=t2;t2=t3;t3=j;
                        break;
                    }
                }
            }
    /*   for(int i=0;i<26;i++)
         for(int j=0;j<26;j++)
           for(int k=0;k<26;k++)
             for(int t=0;t<26;t++)
               if(mark[i][j][k][t]==0)
                  printf("%d%d%d%d
",i,j,k,t);*/
    while(cin>>n)
    {
        if(n>26*26*26*26+3)
        {
            cout<<"Impossible"<<endl;
            continue;
        }
        else
        {
              printf("%s
",s+456979-n);//输出n个字符!后面的是起始地址! 
        }
    }
    return 0;
}


原文地址:https://www.cnblogs.com/yezekun/p/3925785.html