给定一个长度不超过40的数字串s,求斐波那契数列的前十万项中,最小的一个前缀为s的数的下标。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
new Task().solve();
}
}
class Task {
InputReader in = new InputReader(System.in) ;
PrintWriter out = new PrintWriter(System.out) ;
final int N = 50 ;
Tire tire = new Tire() ;
void solve() {
tire.clear() ;
int[][] fib = new int[3][N] ;
Arrays.fill(fib[0] , 0) ;
Arrays.fill(fib[1] , 0) ;
Arrays.fill(fib[2] , 0) ;
fib[0][0] = 1 ;
fib[1][0] = 1 ;
tire.add(fib[0] , 0) ;
for(int n = 2 ; n < 100000 ; n++){
int i = 0 , c = 0 ;
for( ; i < N ; i++){
fib[2][i] = (c + fib[1][i] + fib[0][i]) % 10 ;
c = (c + fib[1][i] + fib[0][i]) / 10 ;
}
if(i == N && c > 0){
for(int k = 0 ; k <= N-2 ; k++){
fib[2][k] = fib[2][k+1] ;
fib[1][k] = fib[1][k+1] ;
}
fib[2][N-1] = c ;
fib[1][N-1] = 0 ;
}
for(int k = 0 ; k < N ; k++){
fib[0][k] = fib[1][k] ;
fib[1][k] = fib[2][k] ;
}
tire.add(fib[2] , n) ;
}
int t = in.nextInt() ;
for(int cas = 1 ; cas <= t ; cas++){
out.println("Case #" + cas + ": " + tire.find(in.next().toCharArray())) ;
}
out.flush() ;
}
}
class Tire{
final int nodeSize = 100000*40 + 8 ;
final int sonSize = 10 ;
int[][] next = new int[nodeSize][sonSize] ;
int[] lable = new int[nodeSize] ;
int root , totel ;
int newNode(){
for(int i = 0 ; i < sonSize ; i++){
next[totel][i] = 0 ;
}
lable[totel] = -1 ;
return totel++ ;
}
void clear(){
totel = 0 ;
root = newNode() ;
}
void add(int[] word , int id){
int now = root ;
int i = word.length - 1 , len = 0 ;
while(i >= 0 && word[i] == 0){
i-- ;
}
while(i >= 0 && ++len <= 40){
if(next[now][word[i]] == 0){
next[now][word[i]] = newNode() ;
}
now = next[now][word[i]] ;
if(lable[now] == -1){
lable[now] = id ;
}
i-- ;
}
}
int find(char[] word){
int now = root ;
for(char c : word){
int i = c - '0' ;
if(next[now][i] == 0){
return -1 ;
}
now = next[now][i] ;
}
return lable[now] ;
}
}
class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = new StringTokenizer("");
}
private void eat(String s) {
tokenizer = new StringTokenizer(s);
}
public String nextLine() {
try {
return reader.readLine();
} catch (Exception e) {
return null;
}
}
public boolean hasNext() {
while (!tokenizer.hasMoreTokens()) {
String s = nextLine();
if (s == null)
return false;
eat(s);
}
return true;
}
public String next() {
hasNext();
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}