Числа Фибоначчи. Объяснить код

228
07 февраля 2020, 14:00

Дано: Для решения задачи считываем два целых числа i и j такие, что 1 ≤ i, j ≤ 10^6.

Найти: Нужно вывести остаток от деления НОД чисел Fi и Fj на 10^9.

Решение: По свойству из Википедии: «Наибольший общий делитель двух чисел Фибоначчи равен числу Фибоначчи с индексом, равным наибольшему общему делителю индексов», получаем, что НОД(F_n,F_m) = F_{НОД(n,m)}.

Значит, нам нужно найти НОД для чисел i и j из условия, после чего найти соответствующее число Фибоначчи по модулю 1000000000.

Код от Harry:

#include <fstream>
using namespace std;
int nod(int a, int b) // Алгоритм Евклида
{
    while (a && b) if (a > b) a %= b; else b %= a;
    return a + b;
}
int main()
{
    int i, j; // вводимые числа
    ifstream fin;
    fin.open("INPUT.TXT");
    fin >> i >> j; // считываем i и j
    fin.close();
    int F0 = 0, F1 = 1; // по условию
    for (i = nod(i, j); i > 0; --i)  // ищем нужное число..
    {
        int F = (F0 + F1) % 1000000000;// .. по модулю 1000000000
        F0 = F1;
        F1 = F;
    }
    ofstream fout;
    fout.open("OUTPUT.TXT");
    fout << F0; //остаток от деления НОД чисел Fi и Fj на 10^9
    fout.close();
    return 0;
}

Я не очень понимаю фразу: "после чего найти соответствующее число Фибоначчи по модулю 1000000000". Может ли кто-то объяснить ее и соответствующую часть кода подробнее? Т.е. вот эту:

for (i = nod(i, j); i > 0; --i)  // ищем нужное число..
{
    int F = (F0 + F1) % 1000000000;// .. по модулю 1000000000
    F0 = F1;
    F1 = F;
}

Заранее спасибо!

Answer 1

Найти соответствующее число Фибоначчи по модулю 1000000000 - значит находим число Фибоначчи и берем остаток от деления его на 1000000000.

for (i = nod(i, j); i > 0; --i)  // ищем нужное число..

Тело цикла выполнится столько раз, сколько вернула функция nod. Если вернулось 3, то i примет значения 3, 2, 1, и когда станет 0, в цикл мы уже не войдем.

{
    int F = (F0 + F1) % 1000000000;// .. по модулю 1000000000

Находим следующее число Фибоначчи по модулю 1000000000 (оператор % находит остаток от деления). Если не находить остаток на каждой итерации, типа чтобы потом 1 раз в конце посчитать, тогда случится переполнение и ответ испортится.

    F0 = F1;
    F1 = F;

Большее число записывается на место меньшего, а новое - на место большего. Ну например:
3, 5 было
5, 8 стало

}
READ ALSO
Узнать находится ли курсор в ВИДИМОЙ части окна

Узнать находится ли курсор в ВИДИМОЙ части окна

Есть главное окно, на этом главном окне расположен некий визуальный компонентИспользуя SetCapture в этот визуальный компонент всегда приходят...

215
Выдается ошибка при вызове функции front() в шаблоне очереди с++

Выдается ошибка при вызове функции front() в шаблоне очереди с++

Я делаю очередь с помощью шаблонаДобавляю туда элементы в виде структур, однако при вызове функции front() (которая должна выводить первую добавленную...

201
Поймать конец скролла на JQuery

Поймать конец скролла на JQuery

Если запустить ниже код, будет видно что производится автоматический скролл в конец объектаКогда пользователь скроллит вверх до объекта...

285
Прикрепить элемент к стенке браузера

Прикрепить элемент к стенке браузера

Необходимо прикрепить элемент к стенке браузера, чтобы тот взаимодействовал(шапка спускалась) вместе с прокруткой страницы внизНО, при этом...

244