У меня есть целое число N. Я должен найти наименьшее целое число больше N, которое не содержит цифр, кроме 0 или 1. Например: если N = 12
тогда ответ - 100
. Я кодировал подход грубой силы в C ++.
int main() {
long long n;
cin >> n;
for (long long i = n + 1; ; i++) {
long long temp = i;
bool ok = true;
while (temp != 0) {
if ( (temp % 10) != 0 && (temp % 10) != 1) {
ok = false;
break;
}
temp /= 10;
}
if (ok == true) {
cout << i << endl;
break;
}
}
}
Проблема в том, что мой подход слишком медленный. Я считаю, что есть очень эффективный подход для решения этой проблемы. Как я могу решить эту проблему эффективно?
N
Разрешен ли отрицательный ? Кроме того, это сложно, так как вы рискуете переполнить ваш тип. Каковы границыN
?Ответы:
Инкремент N,
Начиная слева, сканируйте, пока не найдете цифру выше 1. Увеличьте частичное число перед ним и обнулите остальные.
Например
Доказательство:
Запрашиваемое число должно быть не менее N + 1, поэтому мы увеличиваем его. Сейчас мы ищем число больше или равно.
Давайте назовем префикс начальными цифрами 0/1 и суффикс после. Мы должны заменить первую цифру суффикса на ноль и установить больший префикс. Наименьший подходящий префикс - это текущий префикс плюс один. И самый маленький подходящий суффикс - это все нули.
Обновить:
Я забыл указать, что префикс должен увеличиваться как двоичное число , иначе могут появиться запрещенные цифры.
источник
Другая возможность будет следующей:
Вы начинаете с наибольшего десятичного числа типа "1111111 ... 1111", поддерживаемого используемым типом данных
Алгоритм предполагает, что входное значение меньше этого числа; в противном случае вам придется использовать другой тип данных.
Пример: при использовании
long long
вы начинаете с номера1111111111111111111
.пример
Доказательство правильности:
В этом алгоритме мы обрабатываем цифру за цифрой. На каждом шаге есть цифры, значение которых уже известно, и цифры, значения которых еще не известны.
На каждом шаге мы проверяем крайнюю левую неизвестную цифру.
Мы устанавливаем эту цифру на «0», а все остальные неизвестные цифры на «1». Поскольку исследуемая цифра является самой значимой из неизвестных цифр, результирующее число представляет собой наибольшее возможное число, причем эта цифра равна «0». Если это число меньше или равно входному значению, измеряемая цифра должна быть «1».
С другой стороны, результирующее число меньше всех возможных чисел, где исследуемая цифра равна «1». Если результирующее число больше, чем ввод, цифра должна быть «0».
Это означает, что мы можем вычислить одну цифру на каждом шаге.
Код C
(Код C должен работать и на C ++):
источник
Позвольте мне предложить пару альтернатив.
I. Увеличение. Считайте это модификацией метода @YvesDaoust.
(a), если она меньше 2, затем оставьте все как есть
(b) в противном случае установите его на 0 и увеличьте предыдущий
Примеры:
Вы получите результат в десятичном формате.
II. Разделив.
(a), если M превышает 1, затем увеличьте D
(b), в противном случае увеличьте сумму на M * 10 k , где k - текущий номер итерации (начиная с 0)
Пример 1:
Пример 2:
Пример 3:
Пример 4:
источник