Challenge: Count Palindromes
Subdomeniu: Combinatorics (combinatorics)
Scor cont: 140.0 / 140
Submission status: Accepted
Submission score: 1.0
Submission ID: 464834583
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/count-palindromes/problem
Cerinta
A string is made of only lowercase latin letters (a,b,c,d,.....,z). Can you find the length of the lexicographically smallest string such that it has exactly $K$ sub-strings, each of which are palindromes?
Input Format
The first line of input contains single integer $T$ - the number of testcases.
T lines follow, each containing the integer $K$.
Output Format
Output exactly $T$ lines. Each line should contain single integer - the length of the lexicographically smallest string.
Constraints
* $1 \leq T \leq 100$
* $1 \leq K \leq 10^{12}$
Cod sursa
#include <bits/stdc++.h>
using namespace std;
// Count Palindromes - HackerRank
// Given K, output the length of the lexicographically smallest string with exactly K palindromic substrings.
static inline __int128 sum_arith(long long first, long long len){
// first + (first+1) + ... + (first+len-1)
__int128 L = len;
__int128 a = first;
return L * (2*a + (L-1)) / 2;
}
static long long max_len_run(long long k, long long firstCost){
// maximum L >= 1 such that sum_arith(firstCost, L) <= k
// Solve: L^2 + (2*firstCost-1)L - 2k <= 0
long double b = (long double)(2*firstCost - 1);
long double disc = b*b + (long double)8.0L * (long double)k;
long double root = sqrt(disc);
long long L = (long long)floor((-b + root) / 2.0L);
if(L < 1) L = 1;
while(sum_arith(firstCost, L) > (__int128)k) L--;
while(sum_arith(firstCost, L+1) <= (__int128)k) L++;
return L;
}
static long long solve_one(long long k){
long long ans = 0;
long long costA = 1; // cost to append 'a'
long long costB = 1; // cost to append 'b' (1 only before first 'b', then becomes 2)
while(k > 0){
if(costA <= k){
long long L = max_len_run(k, costA);
__int128 s = sum_arith(costA, L);
k -= (long long)s;
ans += L;
costA += L;
} else if(costB <= k){
k -= costB;
ans += 1;
if(costB == 1){
costA = 2;
costB = 2;
} else { // costB == 2
costA = 3;
}
} else {
// only possible when k == 1: append 'c'
ans += 1;
k -= 1;
}
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while(T--){
long long K;
cin >> K;
cout << solve_one(K) << "\n";
}
return 0;
}
HackerRank Combinatorics – Count Palindromes
