27 · abc串
有一个字符串集合,所有字符串的长为 n, 只由 'a', 'b', 'c' 三种字符组成,而且每个字符串中,所有相邻字符都是不同的。
请编写一个程序,返回这个字符串集合中,字典序第 k 小的字符串。
1≤n≤1051 \le n \le 10^51≤n≤105.
1≤k≤10181 \le k \le 10^{18}1≤k≤1018.
如果所有可组成的字符串个数小于 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;
}