Su(n) > n: So doi (abundant)

Một phần của tài liệu sáng tạo trong thuật toán và lập trình (Trang 63 - 68)

So tong doi la so la tong cua 2 so doi.

Moi so tu nhien lon hon 28123 deu la so tong doi. Tinh tong cua cac so khong tong doi.

6965 so abudant. Tim duoc 1456 so Tim duoc 1456 so ---*/ #include <iostream> #include <math.h> using namespace std; #define abundant 2 #define perfect 0

#define deficient 1 #define asum 4

const int mn = 28124; int a[mn];

int b[mn]; // danh sach cac so abudant int k;

// Tong cac uoc < n cua n int Su(int n) { int u, c = (int)sqrt(n), s; if (n == 1) return 0; s = 1; if (c*c == n) { s += c; --c; } for (u = 2; u <= c; ++u) if (n % u == 0) s += u + (n/u); return s; } int Scan() { int i, d, k = 0; memset(a,0,sizeof(a)); for (i = 1; i < mn; ++i) { d = Su(i); if (d == i) a[i] = perfect;

else if (d < i) a[i] = deficient; else { a[i] = abundant; b[++k] = i; } } return k; } void ShowAbudant() { int i;

cout << endl << k << " so abudant: " << endl; cout << endl; cin.get();

for (i = 1; i <= k; ++i) cout << b[i] << " "; }

void ShowAll() { int i;

cout << endl << " Danh sach tong the: " << endl; for (i = 1; i < mn; ++i) {

cout << i << ":"; switch(a[i]) {

case perfect: cout << "p "; break; case deficient: cout << "d "; break;

case abundant: cout << "a "; break; }

} } }

// Cac so la tong cua 2 abudant int Asum() { int i, j, s; for (i = 1; i <= k; ++i) for (j = 1; j <= k; ++j) { s = b[i]+b[j]; if (s < mn) a[s] = asum; }

s = 0; for (i = 1; i < mn; ++i) for (i = 1; i < mn; ++i) if (a[i] != asum) { s += i; } return s; } void TestAbudant() { int i; for (i = 1; i <= k; ++i) {

cout << endl << b[i] << " " << Su(b[i]); cin.get(); }

}

void Run() { int i; k = Scan();

cout << endl << endl << " Total: " << Asum(); // 4179871

}

main() { Run();

cout << endl << " Fini !"; cin.get();

} Problem 25 Problem 25

30 August 2002

The Fibonacci sequence is defined by the recurrence relation: Fn = Fn 1 + Fn 2, where F1 = 1 and F2 = 1.

Hence the first 12 terms will be:

F1=1, F2=1, F3=2, F4=3, F5=5, F6=8, F7=13, F8=21, F9=34, F10=55, F11=89, F12 = 144. The 12th term, F12, is the first term to contain three digits. (adsbygoogle = window.adsbygoogle || []).push({});

What is the first term in the Fibonacci sequence to contain 1000 digits?

Tính trực tiếp Cài đặt phép cộng và phép gán các số lớn. Tính gần đúng: Kí hiệu 2 5 1 

 . Gọi fn là số Fibonacci thứ n (tính từ 1). Dùng qui nạp toán học có thể chưng minh được n-2 < fnn-1. Ta biết số chữ số của số nguyên dương n là int(lg(n))+1, trong đó int(x) là hàm lấy phần nguyên của số thực x, lg là hàm logarithm cơ số 10 (trong C viết là log10).

Vì hàm lg là đồng biến nên bất phương trình kép trên cho ta (n-2) + 1 < lg(fn) + 1  (n-1) +1.

/*--- E25 Find the first term of Fibonacci sequence E25 Find the first term of Fibonacci sequence to contain 1000 digits

---*/ #include <iostream> #include <iostream>

#include <math.h>

using namespace std;

#define Max(a,b) ((a > b) ? a : b) #define Min(a,b) ((a > b) ? b : a) const int mn = 1000;

int lena, lenb, lenc; int a[mn], b[mn], c[mn]; // c = a + b;

void Plus() {

memset(c,0,sizeof(c)); lenc = Max(lena, lenb); int i, v = 0;

for (i = 0; i < lenc; ++i) { v = v + a[i] + b[i]; c[i] = v % 10; v /= 10; } while (v) { c[lenc++] = v % 10; v /= 10;} } int Fib(int n) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); a[0] = b[0] = 1; lena = lenb = 1; lenc = 0; int i = 2; while (lenc < n) { Plus();

memcpy(a, b, sizeof(b)); lena = lenb; memcpy(b, c, sizeof(c)); lenb = lenc; ++i; } return i; } // f(n) <= x^(n-1); m = lg(f{n)) = (n-1)lg(x) // m/lg(x)+1 main() {

cout << endl << endl ; int n = 1000; int m; float x = (sqrt(5)+1)/2; float y = log10(x);

cout << endl << (int)pow(x,n-2) << " " << (int)pow(x,n-1);

cout << endl << (int(n/y) + 1); cout << endl << Fib(n); // 4785

cout << endl << lena << " " << lenb << " " << lenc; cout << endl << " Fini !";

cin.get(); }

Problem 26

13 September 2002

A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:

1/2 /2 = 0.5 1 /3 = 0.(3) 1 /4 = 0.25 1 /5 = 0.2 1 /6 = 0.1(6) 1 /7 = 0.(142857) 1 /8 = 0.125 1 /9 = 0.(1) 1 /10 = 0.1

Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.

Find the value of d 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.

Fib

Dãy số nguyên đựơc gọi là tựa Fibonacci ...,f-2, f-1, f0, f1, f2, ... có tính chất fi = fi-1+fi-2. Biết 5 giá trị i, fi, j, fj, n, i ≠ j. Viết hàm Fib(i, fi, j, fj, n) tính fn ?

Thí dụ Fib(0, 7, -5, -1, 3) = 29. Ý nghĩa: Biết f0 = 7, f-5 = -1 ta tính được f3 = 29 -1 2 1 3 4 7 11 18 29

Thuật toán

Giả sử i < j. (adsbygoogle = window.adsbygoogle || []).push({});

Nếu n = i ta cho kết quả fn = fi, Nếu n = j ta cho kết quả fn = fj, Nếu n ≠ i ta xử lý như sau.

Gọi ci, i = 1, 2, … là dãy Fibonacci chuẩn, tức là dãy c1=1, c2=1, c3 = c2+c1 = 2, ,..., ci = ci-1+ci-2 ; i = 3, 4, …. Ta tìm cách biểu thị dãy tựa Fibonacci qua dãy Fibonacci chuẩn.

Đặt k = j-i. Đặt fi = a, fi+1 = b. Ta có fi = a,

fi+1 = b,

fi+2 = fi+1 + fi = a + b,

fi+3 = fi+2 + fi+1 = (a+b) + b = a + 2b = a.c2 + b.c3

fi+4 = fi+3 + fi+2 = (a.c2 + b.c3) + (a+b) = a(c2 + 1) + b(c3+1) = a.c3 + b.c4. Tổng quát:

fj = fi+k = a.ck-1 + b.ck = fi.ck-1 + b.ck (*) Từ đây suy ra b = (fj - fi.ck-1)/ck

Biết fi = a, fi+1 = b ta dễ dàng tính được n như sau: Nếu i < n ta tính dần fi theo chiều xuôi, từ i = i+2 đến n:

if (i < n) {

for (i = i+2; i <= n; ++i) { t = a + b; a = b; b = t; }

return b; }

Một phần của tài liệu sáng tạo trong thuật toán và lập trình (Trang 63 - 68)