现在的位置: 首页 > 综合 > 正文

hdu 4850 Wow! Such String! 2014西安全国邀请赛

2018年04月25日 ⁄ 综合 ⁄ 共 1424字 ⁄ 字号 评论关闭

构造题就是这样,总是让人埋怨当初太SB。。

首先,要注意这里字符串最长为26^4+3,因为一共有26^4个不同的字符串,每个串占用一个开头,+3是最后的那个串末尾的三个。

然后以aaaabbbbcccc....为开头枚举,先枚举26*4个,之后对每一位从a~z,看能否放这个letter(如果没有前面的26*4个string,这个过程中是不会出现XXXX型的,具体原因木有想清楚,%>_<%,可能和len++后填的下一位数是从X之后开始的有关?),这样枚举的总数也正好是26^4+3

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include <ctype.h>
#include<map>
#include<time.h>
#include<bitset>
using namespace std;
//hdu 4853

const int maxn=500010;
int vis[26][26][26][26];
int str[maxn];
int n;
int len;
void init()
{
    memset(vis,0,sizeof(vis));
    len=0;
    for(int i=0;i<26;i++)
    {
        //vis[i][i][i][i]=1; 不是四个四个一组标记为1,这种case只能标记 1234=1 5678=1,少了2345=1,3456=1这种
        str[len]=str[len+1]=str[len+2]=str[len+3]=i;
        len+=4;
    }
    for(int i=0;i<len-3;i++)
    {
        vis[str[i]][str[i+1]][str[i+2]][str[i+3]]=1;
    }
    while(true)
    {
        bool flg=true;
        //int cnt=0;
        for(int i=0;i<26;i++)
        {
            if(!vis[str[len-3]][str[len-2]][str[len-1]][i])
            {
                //if(str[len-3]==str[len-2]&&str[len-1]==str[len-2]&&str[len-1]==i) cout<<i<<" "<<(cnt++)<<endl; 枚举不到XXXX这种
                vis[str[len-3]][str[len-2]][str[len-1]][i]=1;
                str[len]=i;
                len++;
                flg=false;
            }
        }
        if(flg) break;
    }
   // cout<<len<<endl;

}
int main()
{
    freopen("input.txt","r",stdin);
    //freopen("data.txt","r",stdin);
    //freopen("out1.txt","w",stdout);
    //cout<<pow(26,4)+3<<endl;
    init();
    while(scanf("%d",&n)!=EOF)
    {
        if(n>len) printf("Impossible\n");
        else
        {
            for(int i=0;i<n;i++)
            {
                printf("%c",'a'+str[i]);
            }
            printf("\n");
        }

    }

     return 0;
}





抱歉!评论已关闭.