2011-gre-cs-practice-book.pdf/Q46 — различия между версиями
Материал из DISCOPAL
(→Ответы) |
(→Объяснение) |
||
Строка 39: | Строка 39: | ||
=== Объяснение === | === Объяснение === | ||
− | + | ||
{{cstest-source|2011-gre-cs-practice-book.pdf|46|46}} | {{cstest-source|2011-gre-cs-practice-book.pdf|46|46}} | ||
− | Если | + | Разберём каждое из утверждений |
+ | |||
+ | '''инвариант цикла''' – это некоторое утверждение о переменных, которое остаётся истинным: | ||
+ | |||
+ | * '''перед входом''' в цикл, | ||
+ | * '''после каждой итерации''' цикла (если цикл продолжается), | ||
+ | * '''при завершении''' цикла. | ||
+ | |||
+ | |||
+ | * I: <m>i < 10</m> или <m>j < 10</m> | ||
+ | |||
+ | *# Условие цикла: <m>i < 10 \land j < 10</m>. | ||
+ | *# Если мы '''находимся внутри цикла''', то одновременно <m>i < 10</m> и <m>j < 10</m> (то есть и то, и другое меньше 10). | ||
+ | *#* Из того, что <m>i < 10</m> '''и''' <m>j < 10</m>, автоматически следует более слабое утверждение <m>i < 10</m> '''или''' <m>j < 10</m>. | ||
+ | |||
+ | *# Значит, пока цикл ещё не прерван, утверждение «<m>i < 10</m> или <m>j < 10</m>» будет верно всегда (оно слабее, чем само условие цикла). | ||
+ | *# '''I действительно является инвариантом'''. | ||
+ | |||
+ | --- | ||
+ | |||
+ | * II: <m>i < 11</m> и <m>j < 11</m> | ||
+ | |||
+ | *# Во время работы цикла <m>i</m> и <m>j</m> могут принимать значения от <m>0</m> до <m>9</m> включительно. | ||
+ | *#* Как только <m>i</m> станет равным <m>10</m> (или <m>j = 10</m>), цикл прервётся. | ||
+ | *# Внутри цикла мы имеем <m>i \le 9</m> и <m>j \le 9</m>. | ||
+ | *#* Отсюда немедленно следует, что <m>i < 11</m> и <m>j < 11</m>. | ||
+ | *# При приращении <m>i</m> или <m>j</m> на <m>1</m> они не могут «перескочить» сразу через <m>11</m>, так что в любой момент внутри цикла условие <m>i < 11</m> и <m>j < 11</m> сохраняется. | ||
+ | |||
+ | *# '''II тоже является инвариантом''' (он даже слабее, чем <m>i < 10 \land j < 10</m>, но тем не менее остаётся истинным всюду, пока цикл не завершён). | ||
+ | |||
+ | --- | ||
+ | |||
+ | * Утверждение III: <m>k = i + j</m> | ||
+ | |||
+ | *# Проверим на шагах цикла: | ||
+ | *#* '''Начальные значения''': <m>i = 0</m>, <m>j = 0</m>, <m>k = 0</m>. | ||
+ | *#*# Очевидно, <m>k = i + j = 0</m>. Утверждение верно перед входом в цикл. | ||
+ | |||
+ | *#* '''Шаг цикла''': | ||
+ | *#*# Если <m>A[i] > B[j]</m>, то выполняется: | ||
+ | <m> | ||
+ | k = k + 1, \quad i = i + 1. | ||
+ | </m> | ||
+ | *#*# Новая сумма <m>(i + j)</m> увеличится на <m>1</m> (так как <m>i</m> увеличили на <m>1</m>, <m>j</m> не трогали). Параллельно <m>k</m> тоже увеличился на <m>1</m>. Значит, соотношение <m>k = i + j</m> сохранится. | ||
− | + | *#*# Если <m>A[i] \le B[j]</m>, то выполняется: | |
− | + | <m> | |
− | + | k = k + 1, \quad j = j + 1. | |
+ | </m> | ||
+ | *#*# Аналогично, теперь <m>(i + j)</m> снова увеличилось на <m>1</m> (увеличился <m>j</m>), и <m>k</m> тоже на <m>1</m>. Значит, <m>k</m> остаётся равным <m>i + j</m>. | ||
− | < | + | *# После каждой итерации связь <m>k = i + j</m> сохраняется. |
+ | *# '''III однозначно является инвариантом'''. | ||
{{question-ok|}} | {{question-ok|}} | ||
{{reserve-task|[[Участник:Nikitashapovalov|Nikitashapovalov]] 20:53, 8 января 2025 (UTC)}} | {{reserve-task|[[Участник:Nikitashapovalov|Nikitashapovalov]] 20:53, 8 января 2025 (UTC)}} |
Версия 23:24, 8 января 2025
Вопрос: Q46-08c765
i = 0; j = 0; k = 0; while (i < 10 and j < 10) { if (A[i] > B[j]) { C[k] = A[i]; k = k + 1; i = i + 1; } else { C[k] = B[j]; k = k + 1; j = j + 1; } }
Какие из следующих утверждений могут служить инвариантом цикла для указанного выше цикла while?
I.i<10i<10или
j<10j<10II.
i<11i<11и
j<11j<11III.
k=i+jk=i+j
Ответы
- (A) Только I
- (B) I и II
- (C) I и III
- (D) II и III
- Правильный ответ: (E) I, II и III
Объяснение
Исходники — вопрос 46 на 46 странице книги «2011-gre-cs-practice-book.pdf»
Разберём каждое из утверждений
инвариант цикла – это некоторое утверждение о переменных, которое остаётся истинным:
- перед входом в цикл,
- после каждой итерации цикла (если цикл продолжается),
- при завершении цикла.
- I: или
- Условие цикла: .
- Если мы находимся внутри цикла, то одновременно и (то есть и то, и другое меньше 10).
- Из того, что и , автоматически следует более слабое утверждение или .
- Значит, пока цикл ещё не прерван, утверждение « или » будет верно всегда (оно слабее, чем само условие цикла).
- I действительно является инвариантом.
---
- II: и
- Во время работы цикла и могут принимать значения от до включительно.
- Как только станет равным (или ), цикл прервётся.
- Внутри цикла мы имеем и .
- Отсюда немедленно следует, что и .
- При приращении или на они не могут «перескочить» сразу через , так что в любой момент внутри цикла условие и сохраняется.
- Во время работы цикла и могут принимать значения от до включительно.
- II тоже является инвариантом (он даже слабее, чем , но тем не менее остаётся истинным всюду, пока цикл не завершён).
---
- Утверждение III:
- Проверим на шагах цикла:
- Начальные значения: , , .
- Очевидно, . Утверждение верно перед входом в цикл.
- Начальные значения: , , .
- Проверим на шагах цикла:
- Шаг цикла:
- Если , то выполняется:
- Шаг цикла:
- Новая сумма увеличится на (так как увеличили на , не трогали). Параллельно тоже увеличился на . Значит, соотношение сохранится.
- Если , то выполняется:
- Аналогично, теперь снова увеличилось на (увеличился ), и тоже на . Значит, остаётся равным .
- После каждой итерации связь сохраняется.
- III однозначно является инвариантом.
Задача зарезервирована: Nikitashapovalov 20:53, 8 января 2025 (UTC)