Fork me on GitHub

A very funny problem from Google Code Jam.

Briefly:

Find the last three digits before the decimal point for the number .

This remind me of the closed form formula of Fibonacci series1, if you don’t have patients, jump to Proof.

###Start from Fibonacci

The closed form formula:

It is interesting to have an irrational expression derived to an integral result. The trick is that there are two parts aside the subtraction, both of which have irrational components, but cancel with each other.

Moreover, the two parts are not equally important, the first one is the main part, while the second one is always less than 1 because is. For the nth Fibonacci number, the first part already have a very good guess. The second one is a residual to pull the values from irrational to an integer, the accurate one.

Inspired by this, I claim that

must always be an integer, with a,b,c integers. It’s easy to prove that via induction, or you can think of this as a complex number with a took the place of .

###Induction Proof If we represent:

then we have:

is an integer. So we are to prove that the representation exists. This is obvious when , assume this holds for , then

also holds for .

And we have the transformation:

Now it’s easy to solve through .

Put in , we know that the second part is always less than 1, it makes up to 1 with a minor part from . Thus the integral part of is exactly 1 less than .

###Code The code is simple compare to the deducing:

#include <stdio.h>

int main() {
	int T; scanf("%d", &T);
	for (int t = 1; t <= T; ++t) {
		int n; scanf("%d", &n);
		int a = 1, b = 0;
		for (unsigned bit_flag = 1 << 31; bit_flag > 0; bit_flag >>= 1) {
			// A_n = (A_{n/2})^2
			int a2 = a*a + 5*b*b;
			int b2 = 2*a*b;
			a = a2 % 1000, b = b2 % 1000;

			if (bit_flag & n) {
				// A_n = A_{n-1} * (3 + \sqrt 5)
				int a2 = 3*a + 5*b;
				int b2 = a + 3*b;
				a = a2 % 1000, b = b2 % 1000;
			}
		}

		printf("Case #%d: %03d\n", t, (2*a-1)%1000);
	}
	return 0;
}
2014-08-09


blog comments powered by Disqus