The meaning of problems
$ S (1) = "COFFEE", S (2) = "CHICKEN" $, $ S (n) = S (n-2) + S (n-1) $, please output $ S (n) $ in starting from the $ k $ characters 10 characters (if 10 output is insufficient to the end of can), $ 1 \ leq n \ leq 500, 1 \ leq k \ leq min ({| S (n) |, 10 ^ {12}}) $.
analysis
Note $ f (i) $ represents $ S (i) $ length, $ f (i) = f (i-2) + f (i-1) $.
Recursive call $ solve (n, k) $ represents $ S (n) $ of $ k $ characters.
If $ n \ leq 2 $ return directly answer,
$ N> 2 $, if $ k> f (i-2) $, calls $ solve (n-1, kf (n-2)) $; otherwise the call $ solve (n-2, k) $.
Note that Japanese sentence $ k> f (n) $.
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 510; char s1[10] = "COFFEE"; char s2[10] = "CHICKEN"; ll n, k; ll f[maxn]; void init() { f[1] = 6;f[2] = 7; int i; for(i = 3; I <MAXN; I ++ ) { F [I] = F [I- 2 ] + F [I- . 1 ]; IF (F [I]> 1e12 + 10 ) BREAK ; } for ( int J = I + . 1 ; J < MAXN; J ++) // more than 1e12, directly by the equal process, or will overflow F [J] = F [I]; } char Solve (LL n-, LL K) { IF (K> F [n-]) return ' A ' ; IF (n-== . 1 ) return S1 [- K- . 1 ]; IF(n == 2) return s2[k-1]; if(k > f[n-2]) return solve(n-1, k-f[n-2]); else return solve(n-2, k); } int main() { init(); int T; scanf("%d", &T); while(T--) { scanf("%lld%lld", &n, &k); for(int i = 0;i < 10;i++) { char ch = solve(n, k+i); if(ch == 'A') break; printf("%c", ch); } printf("\n"); } }