Fibonacci strings#2524

Fibonacci strings (Editorial)

Fibonacci strings are defined recursively:

F_n = F_{n-2} + F_{n-1}

This means that the string F_n consists of two consecutive parts:

Therefore, to find the -th character of the string F_n, it is not necessary to construct the entire string. It is enough to determine in which of the two parts it lies.

Let F_n(k) denote the -th character of the string F_n.

Then:

F_n(k) = F_{n-2}(k)
F_n(k) = F_{n-1}(k - |F_{n-2}|)

Thus, the problem reduces to finding a character in strings with smaller indices.

Example

Consider the string F_6, for which the following relations hold:

Let us compute F_6(4). Since k = 4 \le |F_4| = 5, we have F_6(4) = F_4(4).

Let us compute F_6(7). Since k = 7 > |F_4| = 5, we have F_6(7) = F_5(7 - 5) = F_5(2).

Algorithm implementation

The array stores the lengths of the Fibonacci strings:

#define MAX 44
int fib[MAX] = {1, 1};

The function solve returns the -th character of the string F_n without constructing the string itself in full.

char solve(int n, int k)
{

The base cases n = 0 and n = 1 are handled separately.

  if (n == 0) return 'a';
  if (n == 1) return 'b';

It is known that F_n = F_{n - 2} + F_{n - 1}.

  if (k <= fib[n-2]) return solve(n - 2, k);
  return solve(n - 1, k - fib[n-2]);
}

The main part of the program. Compute the first Fibonacci numbers.

for (int i = 2; i < MAX; i++)
  fib[i] = fib[i-1] + fib[i-2];

Read the number of test cases .

scanf("%d",&tests);
while (tests--)
{

Compute and print the answer for each test case.

  scanf("%d %d",&n,&k);
  printf("%c\n",solve(n,k));
}