Nadesłany przez Jan Wojciechowski, 31 marca 2012 23:11
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
fibonacci.cpp:
//ciag fibonacciego O(log n) //Metodą szybkiego potęgowania macierzy //Jan Wojceichowski //www.algorytm.org #include <iostream> using namespace std; //Klasa wektora template<typename T> class Vector { public: Vector(T x = T(0), T y = T(0)) { this->x = x; this->y = y; } Vector(const Vector<T> &v) : x(v.x), y(v.y) { } ~Vector() { } Vector<T> &operator=(const Vector<T> &v) { if(this != &v) { this->x = v.x; this->y = v.y; } return *this; } T x, y; }; //Klasa macierzy o rozmiarze 2x2 template<typename T> class Matrix2x2 { public: Matrix2x2() { this->zero(); } Matrix2x2(const Matrix2x2<T> &mx) { this->copy(mx.data); } ~Matrix2x2() { } Matrix2x2<T> &operator=(const Matrix2x2<T> &mx) { if(this != &mx) { this->copy(mx.data); } return *this; } Matrix2x2<T> operator*(const Matrix2x2<T> &mx) { Matrix2x2<T> result; result.data[0][0] = this->data[0][0] * mx.data[0][0] + this->data[0][1] * mx.data[1][0]; result.data[0][1] = this->data[0][0] * mx.data[0][1] + this->data[0][1] * mx.data[1][1]; result.data[1][0] = this->data[1][0] * mx.data[0][0] + this->data[1][1] * mx.data[1][0]; result.data[1][1] = this->data[1][0] * mx.data[0][1] + this->data[1][1] * mx.data[1][1]; return result; } Vector<T> operator*(const Vector<T> &v) { Vector<T> result; result.x = this->data[0][0] * v.x + this->data[0][1] * v.y; result.y = this->data[1][0] * v.x + this->data[1][1] * v.y; return result; } template<typename I> void power(I n) { Matrix2x2<T> tmp = (*this); this->identity(); while(n > I(0)) { if(n % I(2) == I(0)) { tmp = tmp * tmp; n /= I(2); } else { (*this) = (*this) * tmp; n -= I(1); } } } void zero() { this->data[0][0] = T(0); this->data[0][1] = T(0); this->data[1][0] = T(0); this->data[1][1] = T(0); } void identity() { this->data[0][0] = T(1); this->data[0][1] = T(0); this->data[1][0] = T(0); this->data[1][1] = T(1); } T data[2][2]; private: void copy(const T data[2][2]) { this->data[0][0] = data[0][0]; this->data[0][1] = data[0][1]; this->data[1][0] = data[1][0]; this->data[1][1] = data[1][1]; } }; //Funkcja obliczająca wartosc liczby ciagu Fibonacciego template<typename T, typename I> T fib(I n) { Matrix2x2<T> mx; mx.data[0][0] = T(0); mx.data[0][1] = T(1); mx.data[1][0] = T(1); mx.data[1][1] = T(1); mx.power(n); Vector<T> result = mx * Vector<T>(T(0), T(1)); return result.x; } //Przyklad uzycia int main(int, char **) { typedef unsigned long long Int; cout << "Liczby Fibonacciego" << endl; cout << "Podaj numer liczby Fibonacciego: "; unsigned int n; cin >> n; cin.ignore(); Int result = fib<Int>(n); cout << n << "-ta liczba Fibonacciego: " << result << endl; ::getchar(); return 0; }