База ответов ИНТУИТ

Программирование

<<- Назад к вопросам

Оценить сверху время работы (т.е. количествовыполнений тела цикла) алгоритма Евклидавычисления наибольшего общего делителя двух целых чисел:
int gcd(int m, int n) {    // дано: целые числа m, n, хотя бы одно отлично от нуля    // надо: вычислить НОД пары (m, n)    int a = m, b = n;    while (b != 0) {        // Invariant: НОД(a, b) == НОД(m, n)        int r := a % b; // находим остаток от деления a на b        a = b; b = r;   // заменяем пару (a, b) на (b, r)    }    return a;           // ответ = a}

(Отметьте один правильный вариант ответа.)

Варианты ответа
Время работы не больше, чем C*max(m, n), где C - некоторая константа (т.е. время пропорционально максимальному из чисел m, n).
Время работы не больше, чем C*log2max(m, n), где C - некоторая константа (т.е. время пропорционально количеству цифр в двоичной или десятичной записи максимального из чисел m, n). (Верный ответ)
Время работы не больше, чем C*r, где C - некоторая константа, r - квадратный корень из max(m, n) (т.е. время пропорционально квадратному корню из максимального числа).
Похожие вопросы
Оценить сверху время работы (т.е. количествовыполнений тела цикла) алгоритма быстрого возведения в степень:
int fastPow(double a, int n) {    // дано: основание a и показатель степени n >= 0    // надо: вычислить a в степени n    double b = a, p = 1.0; int k = n;    while (k > 0) {        // Invariant: b^k * p == a^n        if (k%2 == 0) {            // k четное            k /= 2;            b *= b;        } else {            // k нечетное            --k;            p *= b;        }    }    return p;}
Оценить сверху время работы (т.е. количествовыполнений тела цикла) алгоритмаприблизительного вычисления логарифма:
double myLog(double x, double a, double eps) {    // дано: x > 0, a > 1, eps > 0    // надо: вычислить log_a x с точностью eps    double y = 0.0, z = x, t = 1.0;    while (        fabs(t) > eps ||        x <= 1.0/a ||        z >= a    ) {        // Invariant: a^y * z^t == x        if (z >= a) {            z /= a; y += t;        } else if (z <= 1.0/a) {            z *= a; y -= t;        } else {            z *= z; t /= 2.0;        }    }    return y;}
Рассмотрим следующий фрагмент программы, вычисляющейчастное q и остаток r от деленияцелых чисел a, b:
    // дано: целые числа a >= 0, b > 0    int a, b;    . . .    int q = 0, r = a;    int e = 1, m = b;    while (r >= b) {        if (2*m <= r) {            e *= 2; m *= 2;        } else if (m > r) {            e /= 2; m /= 2;        } else {            // утверждение: m <= r && r < 2*m            q += e; r -= m;        }    }    // q и r - частное и остаток от деления a на b
Какое условие является инвариантом цикла?
Рассмотрим следующую функцию, аргументами которойявляются два целых неотрицательных числа:
int f(int m, int n) {    // дано: m >= 0 и n >= 0    int a = m; int b = n;    int c = 1;    while (a != 0 && b != 0) {        if (a%2 == 0 && b%2 == 0) {            // a и b четные            a /= 2; b /= 2;            c *= 2;        } else if (a%2 == 0) {            // a четное, b нечетное            a /= 2;        } else if (b%2 == 0) {            // a нечетное, b четное            b /= 2;        } else {            // a и b нечетные            if (a > b) {                a -= b;            } else {                b -= a;            }        }    } // end while    return c*(a + b);}
Какое условие является инвариантом цикла?(Через НОД и НОК обозначены наибольший общий делитель инаименьшее общее кратное.)
Рассмотрим следующую функцию, аргументами которойявляются два целых неотрицательных числа:
int f(int m, int n) {    int a = m, b = n;    int p = 0;    while (b != 0) {        if (b%2 == 0) { // b четное            b /= 2;            a *= 2;        } else { // b нечетное            --b;            p += a;        }    }    return p;}
Какое условие является инвариантом цикла?
Пусть a - целочисленный массив размера n(индекс элементов меняется от 0 до n-1),элементы которого строго возрастают:a[0] < a[1] <... < a[n-1].Определить, содержит ли следующий фрагмент программы ошибку(т.е. действительно ли тело цикла сохраняет инвариант):
// Программа Поиск    int n; int *a;    . . .    // дано: целое n;    //       целочисленный массив a[n],    //           элементы которого строго возрастают    //           a[0] < a[1] < ... < a[n-1]    // надо: найти элемент x в массиве    int x;          // искомый элемент    . . .           // рассматриваются исключительные случаи    // общий случай    // утверждение: a[0] < x  &&  x <= a[n-1];    int b = 0; int e = n - 1;    while (e - b > 1) {        Invariant: a[b] < x  &&  x <= a[e]        int c := (a + b)/2; // c - целая часть (a+b)/2        if (x < a[c]) {            e = c;  // выбираем левую половину отрезка        } else {            b = c;  // выбираем правую половину        }    }    // утверждение: b == e - 1   &&    //              a[b] < x  &&  x <= a[e]
В алгоритме получения записи числа nв системе счисления с основанием bмы вычисляем цифры числа справа налево,начиная с последней цифры. На очередном шагемы делим n с остатком на b, получаячастное q и остаток r;остаток представляет очередную цифру числа в порядке справа налево.Затем мы переменной nприсваиваем значение частного q,и процесс повторяется,пока n не станет равным нулю.Сколько раз будет выполнена операция деленияпри переводе числа 1000000 (миллион)в шестнадцатеричную систему счисления?
В алгоритме получения записи числа nв системе счисления с основанием bмы вычисляем цифры числа справа налево,начиная с последней цифры. На очередном шагемы делим n с остатком на b, получаячастное q и остаток r;остаток представляет очередную цифру числав порядке справа налево.Затем мы переменной nприсваиваем значение частного q,и процесс повторяется, пока n не станет равным нулю.Сколько раз будет выполнена операция деленияпри переводе числа 2000000 (два миллиона)в восьмеричную систему счисления?
В алгоритме получения записи числа nв системе счисления с основанием bмы вычисляем цифры числа справа налево,начиная с последней цифры. На очередном шагемы делим n с остатком на b, получаячастное q и остаток r;остаток представляет очередную цифру числав порядке справа налево.Затем мы переменной nприсваиваем значение частного q,и процесс повторяется, пока n не станет равным нулю.Сколько раз будет выполнена операция деленияпри переводе числа 1000 (тысяча)в троичную систему счисления?
Следующий фрагмент программы для последовательностивещественных чисел вычисляет количество n элементов,строго меньших предыдущего, причем самый первый элемент такжеучитывается (считается меньше предыдущего).Например, для последовательности{2, 1, 3, 5, 4} ответ n=3(элементы 2, 1 и 4).
n = 0x0 = ...цикл пока в последовательности есть непрочитанные элементы|выполнять|  прочесть очередной элемент посл-ти в <вых: x>|  если x < x0|  | то n = n + 1|  конец если|  x0 = xконец цикла
Каким значением надо инициализировать переменнуюx0, чтобы программа работала правильно?