MrPeeklz 0 / 0 / 0 Регистрация: 02.05.2018 Сообщений: 4 |
||||
1 |
||||
Проверить, является ли заданное натуральное число степенью двойки02.05.2018, 18:05. Показов 147167. Ответов 32 Метки нет (Все метки)
Здравствуйте, форумчане. Есть следующее задание: Дано натуральное число N. Выведите слово YES, если число N является точной степенью двойки, или слово NO в противном случае. Операцией возведения в степень пользоваться нельзя! Что нам надо ввести Натуральное число. Что надо вывести Ответ на задачу в виде:
Что мне изменить, чтобы он не выводил ненужные мне NO?
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
02.05.2018, 18:05 |
32 |
woldemas 654 / 458 / 212 Регистрация: 06.09.2013 Сообщений: 1,266 |
||||
02.05.2018, 18:51 |
2 |
|||
MrPeeklz, у вас ветвь else в цикле каждый раз выполняется, вот он и выводит NO
1 |
Yntra 2 / 2 / 0 Регистрация: 22.04.2018 Сообщений: 18 |
||||
02.05.2018, 18:53 |
3 |
|||
Смысл решения изменять не нужно. Измените код на:
2 |
regio1961 594 / 286 / 178 Регистрация: 06.06.2016 Сообщений: 547 |
||||
02.05.2018, 20:59 |
4 |
|||
Если 0 не считать натуральным числом.
4 |
piece_of_idiocy 0 / 0 / 0 Регистрация: 04.04.2020 Сообщений: 5 |
||||
06.04.2020, 13:42 |
5 |
|||
Собственно, вот:
0 |
lime_is_life 31 / 29 / 2 Регистрация: 24.03.2020 Сообщений: 39 |
||||
26.04.2020, 10:51 |
6 |
|||
Вот так вот:
0 |
Byyf75 0 / 0 / 0 Регистрация: 09.06.2020 Сообщений: 1 |
||||
09.06.2020, 07:51 |
7 |
|||
0 |
outoftime ║XLR8║ 1212 / 909 / 270 Регистрация: 25.07.2009 Сообщений: 4,361 Записей в блоге: 5 |
||||
09.06.2020, 08:20 |
8 |
|||
MrPeeklz, woldemas, Yntra, regio1961, piece_of_idiocy, lime_is_life, Byyf75,
0 |
iSmokeJC Am I evil? Yes, I am! 16274 / 9029 / 2606 Регистрация: 21.10.2017 Сообщений: 20,735 |
||||
09.06.2020, 09:20 |
9 |
|||
3 |
Fudthhh Модератор 2872 / 1573 / 510 Регистрация: 21.02.2017 Сообщений: 4,197 Записей в блоге: 1 |
||||
09.06.2020, 09:25 |
10 |
|||
iSmokeJC, чего ж ты молодой, бумагу то не экономишь?
2 |
║XLR8║ 1212 / 909 / 270 Регистрация: 25.07.2009 Сообщений: 4,361 Записей в блоге: 5 |
|
09.06.2020, 09:27 |
11 |
чего ж ты молодой, бумагу то не экономишь? С какой версии так делать можно?
0 |
Модератор 2872 / 1573 / 510 Регистрация: 21.02.2017 Сообщений: 4,197 Записей в блоге: 1 |
|
09.06.2020, 09:27 |
12 |
outoftime, 3.8.X Моржовый оператор
0 |
║XLR8║ 1212 / 909 / 270 Регистрация: 25.07.2009 Сообщений: 4,361 Записей в блоге: 5 |
|
09.06.2020, 09:32 |
13 |
0 |
Am I evil? Yes, I am! 16274 / 9029 / 2606 Регистрация: 21.10.2017 Сообщений: 20,735 |
|
09.06.2020, 09:33 |
14 |
DmFat, ну, молодозелено, че
0 |
Ergo_py 2 / 2 / 0 Регистрация: 24.08.2020 Сообщений: 15 |
||||
25.08.2020, 12:17 |
15 |
|||
0 |
владикНЕвладик 1 / 1 / 0 Регистрация: 20.04.2019 Сообщений: 59 |
||||
04.11.2020, 18:18 |
16 |
|||
Вот, всё работает
0 |
Am I evil? Yes, I am! 16274 / 9029 / 2606 Регистрация: 21.10.2017 Сообщений: 20,735 |
|
04.11.2020, 18:27 |
17 |
всё работает Не, чет не работает
1 |
1 / 1 / 0 Регистрация: 20.04.2019 Сообщений: 59 |
|
04.11.2020, 18:40 |
18 |
Чувак, это на С++, а ты мучаешь питошку
0 |
Am I evil? Yes, I am! 16274 / 9029 / 2606 Регистрация: 21.10.2017 Сообщений: 20,735 |
|
04.11.2020, 18:45 |
19 |
владикНЕвладик, в самом деле? А я думал в ветке Python на питоне пишут… Добавлено через 1 минуту
0 |
1 / 1 / 0 Регистрация: 20.04.2019 Сообщений: 59 |
|
04.11.2020, 18:45 |
20 |
Сорян, не подумал, но в итоге имея пример даже на другом языке можно же переписать на нужный язык
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
04.11.2020, 18:45 |
Помогаю со студенческими работами здесь Определить, является ли заданное число степенью двойки Определить, является ли натуральное число N степенью двойки Является ли натуральное число точной степенью двойки Определить, является ли заданное число точной степенью двойки Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 20 |
7 Модуль. Цикл while
Цикл while («пока»)
— это так называемый цикл с условием или с предусловием. В цикле for мы
явно указываем, какие значения будет принимать переменная i,
например, 1 <= i <= 10.
В цикле while можно задавать более
сложные условия, например, i ** 2 <= 10,
кроме того можно использовать логические операции «И»,
«ИЛИ» и т.д.
Цикл while позволяет
выполнить одну и ту же последовательность действий, пока проверяемое условие
истинно. Условие записывается до тела цикла и проверяется до выполнения тела
цикла. Как правило, цикл while используется,
когда невозможно определить точное значение количества проходов исполнения
цикла.
Синтаксис цикла while в
простейшем случае выглядит так:
while
условие:
блок инструкций
При выполнении цикла while сначала
проверяется условие. Если оно ложно, то выполнение цикла прекращается, и
управление передаётся на следующую инструкцию после тела цикла while .
Если условие истинно, то выполняются все инструкции из блока, после чего
условие проверяется снова, и снова выполняется блок инструкций. Так
продолжается до тех пор, пока условие будет истинно. Как только условие
становится ложным, работа цикла завершается, и управление передаётся следующей
инструкции после цикла.
Пример:
Следующий фрагмент программы
напечатает на экран всех целые числа, не превосходящие n, и их сумму:
s = 0
i = 1
while i <= n:
print(i)
s +=
i
i +=
1
Пример:
C предыдущей задачей, однако,
мог бы справиться и цикл for .
Рассмотрим более сложную задачу, с которой for уже
не справится: вывести на экран все степени двойки, не превосходящие 100.
Её также удобно решать с помощью цикла while.
i =
1
while
i <= 100:
print(i)
i *=
2
После окончания цикла
значение i будет уже больше, чем 100, иначе цикл бы продолжился.
Последнее напечатанное значение будет соответственно равно 64.
Пример:
Немного изменим задачу:
найдём максимальную степень двойки, не превосходящую 100.
p =
1
while
p * 2 <=
100:
p *=
2
print(p)
После окончания цикла
значение переменной p будет максимальной степенью двойки, не
превосходящей 100, потому что на следующем шаге условие уже не будет
выполняться.
Пример:
Вот еще один пример
использования цикла while для
определения количества цифр натурального числа n и их суммы:
s = 0
n = int(input())
count = 0
while n > 0:
count += 1
s += n %
10
n //= 10
print(count)
print(s)
В этом цикле мы отбрасываем
по одной цифре числа, начиная с конца, что эквивалентно целочисленному делению
на 10 (n //= 10),
при этом считаем в переменной count, сколько раз это было сделано, а в
переменной s — сумму отброшенных цифр.
Задачи.
Трискайдекафобия
Трискайдекафобия — боязнь
числа 13. В особо сложных формах пациент боится и всех чисел,
кратных 13.
Дано число N. Выведите
все целые числа по возрастанию, начиная с числа N, пока не встретится
число, кратное 13. Его выводить не нужно.
Входные данные
Дано натуральное число N, не
превосходящее 10000.
Выходные данные
Выведите ответ на задачу.
Примечание
Программа должна быть решена при помощи
одного цикла while,
без if внутри цикла.
Решение.
Номер числа Фибоначчи
Последовательность Фибоначчи
определяется так:
ϕ0=0, ϕ1=1,
ϕn=ϕn−1+ϕn−2
Дано натуральное
число A. Определите, каким по счету числом Фибоначчи оно является, то есть
выведите такое число n, что ϕn=A. Если A не
является числом Фибоначчи, выведите число −1.
Входные данные
Вводится натуральное
число A (2≤A≤2∗109).
Выходные данные
Выведите ответ на задачу.
Точная степень двойки
Дано натуральное число N. Выведите
слово YES, если число N является точной степенью двойки, или слово NO
в противном случае.
Операцией возведения в степень пользоваться нельзя!
Входные
данные
Вводится
натуральное число, не превосходящее 200.
Выходные
данные
Выведите
ответ на задачу.
Банковские проценты
Вклад в банке составляет x рублей.
Ежегодно он увеличивается на p процентов, после чего дробная часть от копеек отбрасывается.
Определите, через сколько лет вклад составит не менее y рублей. В
задаче запрещено использовать дробные числа.
Входные данные
Программа получает на вход три натуральных числа: x, p, y (x≤2000,p≤100,y≤2000).
Выходные данные
Программа должна вывести одно целое число — ответ на
задачу.
Примечание
Обратите внимание, что вклад в банке измеряется в рублях,
а отбрасывается дробная часть копеек.
Решение
Минимальный простой делитель
Дано целое число, не меньшее 2. Выведите его
наименьший простой делитель.
Входные
данные
Вводится
целое положительное число N≤2∗109.
Выходные
данные
Выведите
ответ на задачу.
Решение
Список квадратов
По данному целому числу N распечатайте
все квадраты натуральных чисел, не превосходящие N, в порядке
возрастания.
Входные
данные
Вводится
натуральное число, не превосходящее 100.
Выходные
данные
Выведите
ответ на задачу.
Решение
Обработка последовательностей
неизвестной длины.
С помощью цикла for
мы могли решать задачи, обрабатывающие
последовательности числовых данных, например, посчитать сумму или произведение
элементов некоторой последовательности с известным числом элементов.
Однако бывают случаи, когда заранее неизвестно
число элементов последовательности, а ввод ограничен тем или иным образом. С
использованием цикла while
можно решать задачи для этого случая. Рассмотрим
пример такой задачи.
Пример:
Дана последовательность натуральных чисел,
заканчивающаяся нулем. Требуется найти произведение и количество этих чисел
(ноль не должен участвовать в нахождении произведения).
Решение
может выглядеть так:
count = 0
prod = 1
elem = int(input())
while elem != 0:
count += 1
prod *= elem
elem = int(input())
print(prod)
print(count)
Рассмотрим
более сложную задачу.
Пример:
Дана последовательность неизвестной длины,
требуется вывести первое число, которое встречается два раза подряд. Гарантируется,
что такое число существует.
Для решения задачи потребуется хранить не только
текущее считанное значение, но и предыдущее:
prev = int(input())
elem = int(input())
while elem != prev:
prev = elem
elem = int(input())
print(elem)
Второй минимум
Последовательность состоит из натуральных чисел и
завершается числом 0. Определите значение второго минимального по
величине элемента в этой последовательности, то есть элемента, который будет
наименьшим, если из последовательности удалить наименьший элемент.
Последнее число 0 не
учитывается. Гарантируется, что в последовательности есть хотя бы два элемента
(кроме завершающего числа 0).
Входные
данные
На вход подаётся последовательность целых неотрицательных
чисел, заканчивающаяся нулём. Все числа в последовательности неотрицательные,
по значению не превосходящие 109.
Выходные
данные
Выведите
ответ на задачу.
Решение
Количество элементов, которые больше предыдущего
Последовательность состоит из натуральных чисел и
завершается числом 0. Определите, сколько элементов этой
последовательности больше предыдущего элемента.
Входные
данные
Вводится последовательность натуральных чисел,
оканчивающаяся числом 0 (само число 0 в
последовательность не входит, а служит как признак её окончания).
Выходные
данные
Выведите ответ на задачу.
Решение
Количество локальных максимумов
Элемент последовательности называется строгим
локальным максимумом, если он строго больше предыдущего и последующего
элементов последовательности. Первый и последний элемент последовательности не
являются локальными максимумами.
Входные
данные
Дана
последовательность натуральных чисел, завершающаяся числом 0.
Гарантируется, что все числа не превосходят 100.
Выходные
данные
Определите
количество строгих локальных максимумов в этой последовательности.
Решение
Среднее значение последовательности
Определите среднее значение всех элементов
последовательности, завершающейся числом 0. Сам ноль в
последовательность не входит.
Использовать массивы в данной задаче нельзя.
Входные данные
Вводится последовательность целых чисел, оканчивающаяся
числом 0 (само число 0 в
последовательность не входит, а служит как признак её окончания).
Выходные данные
Выведите ответ на задачу.
Решение
Самое частое число в последовательности
Последовательность состоит из натуральных чисел,
причем какое-то из чисел составляет более половины от общего числа членов
последовательности. Найдите это число.
Для решения этой задачи запрещено использование массивов
и списков.
Входные данные
На вход подается последовательность натуральных чисел, заканчивающаяся
нулём. Его обрабатывать не нужно. Гарантируется, что все числа не
превосходят 109.
Выходные данные
Выведите ответ на задачу.
Решение
Нам дана последовательность
чисел и известно, что одно из чисел встречается в последовательности более
половины раз. Это число требуется найти.
Воспользуемся следующим
свойством. Если из этой последовательности мы выкинем два различных элемента,
то искомое число по прежнему будет встречаться более половины раз.
Действительно, так как мы выкидываем два различных числа, то максимум один
экземпляр искомого числа будет выкинут и как минимум одно число, не являющееся
искомым, будет выкинуто, поэтому искомое число будет как и прежде встречаться
более половины раз.
Используем это свойство. Будем
запоминать, какое число ans встречалось нам чаще всех и
количество count таких появлений этого числа. Если
счетчик count равен 0, то мы обновляем
переменную ans и увеличиваем счетчик на 1. Если мы встречаем
число, записанное в переменной ans, то мы будем увеличивать счетчик
на 1, в противном случае будем уменьшать его на 1. Каждому уменьшению
счетчика на 1 соответствует увеличение счетчика на 1, которое
было произведено ранее, и такая пара операций равносильна удалению двух разных
чисел из последовательности. Следовательно, по свойству описанному выше, такой
алгоритм найдет нам искомое число и оно будет записано в переменной ans.
Решение:
ans = 0
count
= 0
elem
= int(input())
while
elem != 0:
if
count == 0:
ans = elem
count += 1
elif
elem == ans:
count += 1
else:
count —= 1
elem = int(input())
print(ans)
Выдача сдачи
Имеется неограниченное количество монет в 1, 2, 5, 10 рублей.
Определите, сколькими способами можно выдать сдачу в n рублей. Например, 5 рублей
можно выдать четырьмя способами: 5=2+2+1=2+1+1+1=1+1+1+1+1.
Входные данные
Программа получает на вход натуральное число n,
не превышающее 100.
Выходные данные
Выведите ответ на задачу.
Решение
Решить
данную задачу можно следующим образом:
s = int(input())
cnt = 0
for a
in range(11):
for b
in range(21):
for c in range(51):
for d in range(101):
if a*10+b*5+c*2+d == s:
cnt+=1
print(cnt)
Выдача сдачи — 2
Имеется неограниченное количество монет в 1, 2, 5, 10 рублей.
Определите, сколькими способами можно выдать сдачу в nn рублей. Например, 55 рублей можно выдать четырьмя способами: 5=2+2+1=2+1+1+1=1+1+1+1+1.
Входные данные
Программа получает на вход натуральное число n,
не превышающее 106.
Выходные данные
Выведите ответ на задачу.
Примечание
Правильное решение задачи можно написать, используя всего
один цикл while
.
Решение
Эта статья посвящена одной из наипопулярнейших задач в области программирования. Сложно представить себе программиста, который хотя бы раз в своей карьере не сталкивался с ней.
Существует целый ряд способов её решения. В этой статье будут рассмотрены два, наиболее грамотные из них.
Данные методы считаются таковыми не только в силу своей вычислительной эффективности, но и прежде всего потому, что имеют объективное математическое обоснование.
1.Использование битовых операций
Если
Или в варианте C++ и ему подобных языков
Данное число n является степенью числа 2 или числом 0. Отдельное внимание заслуживает число 1, которое является числом 2 в степени 0.
Таким образом, чтобы проверка была корректной необходимо исключить числа 0 и 1. Например, так:
var n: Integer; … if (n > 1) then if n and (n — 1) = 0 then WriteLn(‘Yes’) else WriteLn(‘No’); |
Или в варианте для C++:
int n ; … if ((n&(n — 1)) == 0) { printf(«Yes»); } else { printf(«No»); } |
2.Использование логарифмов
Этот способ уже был подробно описан в статье «Является ли число степенью другого числа». В данном способе задача проверки, является ли число степенью двойки, рассматривается как частный случай задачи рассмотренной там.
Для выполнения проверки необходимо вычислить логарифм числа по основанию 2 или частное логарифмов проверяемого числа и числа 2 по общему основанию и проверить является ли результат целым числом.
Если используемый язык программирования или библиотека имеют готовую функцию для вычисления логарифма по основанию 2, решение упрощается до предела.
Вариант для Delphi:
function IsPower2(n: Штеупук): boolean; begin if (n>1) then result := (Trunc(Log2(n)) = Log2(n)); else result:=false; end; |
Вариант для C++:
bool isPower2(int n) { if (n>1) { return (double)((int)log2(n)) == log2(n); } else { return false } } |
Так же как и в предыдущем способе необходимо исключить числа 1 и 0. Особенно 0, так как иначе программа выдаст ошибку.
Помимо двух вышеприведённых, существуют и другие способы проверить, является ли число степенью числа 2. Но по своей простоте и, главное, эффективности они не могут с ними соперничать. Поэтому их использование нежелательно.
Ещё один классический способ:
n > 0 && (n & (n - 1)) == 0
Там по ссылке ещё много всяких битовых трюков.
Как это трюк работает? А вот как. Запишем число n
в двоичной системе, и рассмотрим самую правую единицу в двоичном представлении числа n
. У числа n - 1
будет на месте этой единицы ноль, а справа от него единицы:
n : xxxxxx1000
1 : 0000000001
n - 1 : xxxxxx0111
а остальные двоичные цифры (обозначенные как x
) не поменяются. Поэтому после операции &
получится вот что:
n&(n-1): xxxxxx0000
Это число будет равно нулю тогда и только когда, когда все xxxxxx
равны нулю. Единственный случай, где наше соображение не проходит — число 0: там нету «самой правой» единицы вовсе, так что это случай приходится рассматривать отдельно.
Интересно, что gcc и clang выдают на этот код и код из ответа @aepot строго одинаковый ассемблерный код: https://godbolt.org/z/xWx1qT
Тебе же в прошлом вопросе разжевали всё, зачем снова плодить глупые вопросы? Но если ты прошлый вопрос спрашивал, чтобы таким образом проверять на степень двойки, то лучше сразу уходи их профессии. Изучи хотя бы основы построения алгоритмов.
Нормальная и быстрая проверка на степень двойки делается через бинарные операции:
def check2rec(num):
if num == 1:
return True
if num & 1:
return False
return check2rec(num >> 1)
Плюс, эту функцию можно ещё пооптимизировать.
Ну и бенчмарки, чтобы доказать ущербность логарифмического метода:
def check2rec(num):
if num == 1:
return True
if num & 1:
return False
return check2rec(num >> 1)
def check2log(num):
r = log(num, 2)
return int(r) == r
numbers = list()
print('Generating numbers...')
for _ in range(1000):
numbers.append(randint(10000, 1000000))
print('Done!')
start = datetime.datetime.now()
for _ in range(10000):
for n in numbers:
check2rec(n)
print('Rec: ', datetime.datetime.now() - start)
start = datetime.datetime.now()
for _ in range(10000):
for n in numbers:
check2log(n)
print('Log: ', datetime.datetime.now() - start)
Результаты:
Rec: 0:00:07.408942
Log: 0:00:12.101660
Разница почти в 2 раза.
P.S. С такими «знаниями» тебя в более-менее приличное место не возьмут никогда. Изучи сперва программирование (т.е. построение алгоритмов), а не язык. Почитай Вирта, Кормена, или SICP.