hdoj5334

来源:互联网 发布:淘宝店铺都多大尺寸 编辑:程序博客网 时间:2024/06/14 08:42

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5334

题意:给出一个数字K,让我们输出一个字符串。这个字符串必须满足一个要求,那就是这个字符串的不同连续子串的数量和必须等于K;

解题思路:这题一看感觉怪怪的,其实也不是不能做。虽然,我一开始感觉怪怪的,但是不久之后,我变发现了规律。那就是:

在一个串中,有连续的2个相同子串,那么其不同连续子串的数量-1;比如:112345678的不同连续子串的数量为35,12345678的不同连续子串的数量36,正好差1

在一个串中,有连续的3个相同子串,那么其不同连续子串的数量-3;比如:111234567的不同连续子串的数量为33,12345678的不同连续子串的数量36,正好差3

在一个串中,有连续的4个相同子串,那么其不同连续子串的数量-6;比如:111123456的不同连续子串的数量为30,12345678的不同连续子串的数量36,正好差6

对于所有字符都不同的字符串来说(设其长度为m),其不同连续子串的数量=m*(m+1)/2;

所以,很显然,如果K=m*(m+1)/2,那么只要输出1 2 3 4.....m就可以了。但是,如果不想等呢?

那么,就是(m-1)*m/2<K<m*(m+1)/2之间,那么运用上述找出的规律就可以轻而易举的解题了。

下面举一些例子:

29
8
1 1 2 2 2 2 3 4
30
8
1 1 1 1 2 3 4 5
31
8
1 1 2 2 3 3 3 4
30
8
1 1 1 1 2 3 4 5
33
8
1 1 1 2 3 4 5 6
33
8
1 1 1 2 3 4 5 6
35
8
1 1 2 3 4 5 6 7
36
8
1 2 3 4 5 6 7 8

#include <iostream>#include <stdio.h>#include <math.h>using namespace std;int main(){    long long K;    while(~scanf("%I64d",&K))    {        if(K<100)        {            printf("%I64d\n",K);            printf("1");            for(int i=2;i<=K;i++)            {                printf(" 1");            }            printf("\n");        }        else        {            int m1,m2;            K=K*2;            long long a=1+4*K;            m1=(int)((sqrt(double(a))-1)/2);            if((m1*m1+m1==K))            {                printf("%d\n",m1);                printf("1");                for(int i=2;i<=m1;i++)                {                    printf(" %d",i);                }                printf("\n");            }            else            {                int ans[100000+50];                m2=m1+1;                int ans1[4];                int tmp=m2*m2+m2-K;                tmp=tmp/2;                ans1[3]=tmp/6;                tmp=tmp-ans1[3]*6;                ans1[2]=tmp/3;                tmp=tmp-ans1[2]*3;                ans1[1]=tmp;                printf("%d\n",m2);                int num=1;                int pos=1;                for(int j=1;j<=3;j++)                {                    for(int k=1;k<=ans1[j];k++)                    {                        if(j==1)                        {                            ans[pos++]=num;                            ans[pos++]=num;                            num++;                        }                        if(j==2)                        {                            ans[pos++]=num;                            ans[pos++]=num;                            ans[pos++]=num;                            num++;                        }                        if(j==3)                        {                            ans[pos++]=num;                            ans[pos++]=num;                            ans[pos++]=num;                            ans[pos++]=num;                            num++;                        }                    }                }                for(int y=pos;y<=m2;y++)                {                    ans[y]=num++;                }                printf("%d",ans[1]);                for(int x=2;x<=m2;x++)                {                    printf(" %d",ans[x]);                }                printf("\n");            }        }    }    return 0;}


0 0
原创粉丝点击