27 · abc串

27 · abc串
 

有一个字符串集合,所有字符串的长为 n, 只由 'a', 'b', 'c' 三种字符组成,而且每个字符串中,所有相邻字符都是不同的。
请编写一个程序,返回这个字符串集合中,字典序第 k 小的字符串。

1≤n≤1051 \le n \le 10^51≤n≤10​5​​.
1≤k≤10181 \le k \le 10^{18}1≤k≤10​18​​.
如果所有可组成的字符串个数小于 kkk,返回一个空串。
样例

样例 1:

输入:

n = 3
k = 6

输出:

"bac"

解释:

长为 3 的字符串的集合如下:
["aba", "abc", "aca", "acb",
"bab", "bac", "bca", "bcb",
"cab", "cac", "cba", "cbc"]
所以字典序第 6 小的字符串为 "bac"。

 

string kthString(int n, long long k)

{

    

std::string src = "abc";

    std::string ret = "";

    int size = 0;//字符串长度

    int64_t count=0;

    bool bFirst = false;

    int preI = -1;

    int64_t total = 1;

    int tmpN = n-1;

    int num = 1;


 

    if (n >= 63)

    {

        

        int countTwo = 0;

        long long sum = 1;

        while (sum < k)

        {

            countTwo++;

            sum *= 2;

        }

        countTwo = countTwo -1;

        int countNoTwo = n - countTwo-1;

 

        int j = 0;

        preI = -1;

        int countRe = 1;

        if (j < countNoTwo)

        {

            bool bFirst = false;

            while (j + countRe*2 < countNoTwo)

            {

                if (false == bFirst)

                {

                    ret.append("ab");

                    j += 2;

                    bFirst = true;

                }

                else

                {

                    ret.append(ret);

                    j += countRe * 2;

                    countRe = countRe * 2;

                }   

            }

 

            std::string strhalf = ret.substr(0,countRe);

            while(j + 4 < countNoTwo )

            {

                while (j + countRe > countNoTwo)

                {

                    countRe /= 2;

                    strhalf = strhalf.substr(0, strhalf.size() / 2);

                }

                if (j + countRe <= countNoTwo)

                {

                    ret.append(strhalf);

                    j += countRe;

                }

            }


 

            while (j+2 <= countNoTwo)

            {

                ret.append("ab");

                j +=  2;

            }

 

            if (j < countNoTwo)

            {

                ret.append("a");

                j++;

            }   

        }

 

        if (j % 2 == 0)

        {

            preI = 1;

        }

        else

        {

            preI = 0;

        }

        size=j;

 

        int tmpN = countTwo;

        while(tmpN>0)

        {

            total *= 2;

            tmpN--;

        }

        if (k > total * 3)

        {

            return ret;

        }

 

        while (count < k && size < n)

        {

            int i = 0;

            for (; i < 3; i++)

            {

                if (i == preI)

                {

                    continue;

                }

                if (count + total >= k)

                {

                    break;

                }

                count = count + total;

            }

            if (count + total == k)

            {

                preI = i;

                ret.append(std::string(1, src[i]));

                size++;

                while (size < n)

                {

                    int j = 0;

                    int k = 0;

                    for (; k < 3; k++)

                    {

                        if (k == preI)

                        {

                            continue;

                        }

                        j++;

                        if (j == 2)//最后一个

                        {

                            break;

                        }

                    }

                    ret.append(std::string(1, src[k]));

                    preI = k;

                    size++;

                }

            }

            else if (count < k && i <3 && size < n)

            {

                preI = i;

                ret.append(std::string(1, src[i]));

                size++;

                total /= 2;

            }

        }

    

    }

 

else

{

        

    

    while (tmpN >0)

    {

        total *= 2;

        tmpN--;

    }

    if (k > total * 3)

    {

        return ret;

    }

 

    while (count < k && size < n)

    {

        int i = 0;

        for (; i < 3; i++)

        {

            if (i == preI)

            {

                continue;

            }

            if (count + total >= k)

            {

                break;

            }

            count = count + total;

        }

        if (count + total == k)

        {

            preI = i;

            ret.append(std::string(1, src[i]));

            size++;

            while (size < n)

            {

                int j = 0;

                int k = 0;

                for (; k < 3;k++)

                {

                    if (k == preI)

                    {

                        continue;

                    }

                    j++;

                    if (j == 2)//最后一个

                    {

                        break;

                    }

                }

                ret.append(std::string(1, src[k]));

                preI = k;

                size++;

            }

        }

        else if (count < k && i <3 && size < n)

        {

            preI = i;

            ret.append(std::string(1, src[i]));

            size++;

            total /= 2;

        }

    }

}


   return ret;

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值