Форум программистов, компьютерный форум, киберфорум
kuppp
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Нетривиальный способ перевёртывания числа

Запись от kuppp размещена 26.10.2021 в 13:43
Показов 2664 Комментарии 5

Большинство решений базируются на перестановке разрядов в обратном порядке. Я захотел найти какой-нибудь чисто математический способ, и у меня почти это получилось. Далее идёт объяснение этого метода, если вам неинтересно, можете перейти сразу к коду.
Для начала проанализируем двухзначные числа. Возьмём, например, 14. Перевёрнутое число 41.
Для того чтобы перевернуть число 14 без использования банальной перестановки разрядов, а лишь используя простую математику, нужно к 14 прибавить 27, очевидно. Назовём 27 за k:
14+k=41
Как ни странно, у разных двухзначных чисел будет разное число k. Но есть у всех этих k одно общее: они все кратны 9. Это происходит из-за того, что мы работаем в 10-ой системе счисления. Вот несколько примеров:
38;83 k=83-38=45
10;1 k=10-1=9
47;74 k=74-47=27

И тут я понял, что чем больше разница между цифрой десятка и цифрой единиц, тем больше наша k. В примерах выше это отчётливо видно.
Как я уже говорил, все k кратны 9, так давайте поделим k на 9 и назовём получившееся число за kdop:
38;83 k=83-38=45 kdop=k/9=5
10;1 k=10-1=9 kdop=1
47;74 k=74-47=27 kdop=3

И о чудо, мы получаем, что kdop равен разнице между цифрой десятка и цифрой единиц. И наша конечная формула для двухзначного числа будет выглядеть как:
x=N+9*kdop, где N - вводимое число, которое нужно перевернуть; x - выводимое перевёрнутое число
Для трёхзначного числа всё будет идентично, т.е. мы берём разряд сотен и разряд единиц и находим их разницу. Средний разряд не играет никакой роли.

Важное уточнее по поводу формулы x=N+9*kdop:
Знак сложения здесь будет лишь в том случае, когда цифра высшего разряда меньше цифры низшего. Поэтому для обобщения в коде я буду использовать не разницу между этими цифрами, а разность. В объяснении я буду использовать лишь "+" для понятности

Для четырёхзначного и далее алгоритм будет сложнее, ибо местами меняются все разряды, т.е. наша kdop будет получаться
не в одно действие, как раньше. Учитывать придётся не только перестановку низшего и высшего разрядов, но и всех остальных.
Не буду мучить разъяснениями, сразу приведу алгоритм действий на примере 123456:
1. Даётся число 123456
2. Находится разница между высшим и низшим разрядами, kdop1=5
3. Находится разница между вторым и предпоследним разрядами, kdop2=3
4. Находится разница между оставшимися двумя разрядами, kdop3=1
5. суммируем все получившиеся kdopi в виде:
55555
+ 3330
+ 100
Получаем 58985. Это наша kdop
6. Вычисляем перевёрнутое число по формуле: x=N+9*kdop
x=123456+9*58985=654321


Ну и теперь к реализации этого алгоритма на с++

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std;
int Ten(int b) {
    int c=1;
    for (int i=0; i < b; i++) c = c * 10;
    return c;
}
int main() {
    int N, N2, sim = 0, k=0, kdop=0, raz, sim2;
    cin >> N; //само число
    N2 = N;
    //нахождение количества цифр в числе
    while (N2) {
        N2 = N2 / 10;
        sim++;
    }
    sim2 = sim;
 
    for (int i = 1; i <= sim/2; i++) {
        raz = (N / Ten(sim -i)%10 - ((N % Ten(i)) / Ten(i - 1)));
 
        k = 0;
        for (int j = sim2 - i-1; j >= 0;j--) {  
            k = k + Ten(j) * raz;
        }
        k = k * Ten(sim - sim2);
        sim2--;
        kdop += k;
    }
    N2 = N - 9 * kdop;
    cout << N2;
}
Код далеко не идеален и вообще нужность этого способа сомнительна, но у меня и не было цели создать что-то полезное, а лишь найти и показать новый (вроде как новый, по крайней мере, никакой инфы я не нашёл) способ переворачивания числа.

По сути, этот алгоритм можно немного подкорректировать для любой системы счисления, но мне лень это делать)
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 5
Комментарии
  1. Старый комментарий
    Уважаемый kuppp,
    вы очень интересно пишите. Но здесь я хочу обратить ваше внимание вот ещё на что.
    Пусть А и В два, как вы их называете, перевёрнутых числа. И пусть их сумма равна S
    Тогда А + В = S. Отсюда зная S и одно из чисел (А или В) можно найти второе число.
    Вот ваш пример.
    Для чисел 14 и 41 (их сумма равна 55) имеем
    55 - 14 = 41
    55 - 41 = 14

    примечание
    это верно для любых чисел, а не только двузначных.
    Запись от wer1 размещена 26.10.2021 в 14:58 wer1 вне форума
  2. Старый комментарий
    Сумма двух перевёрнутых чисел делится на 11. Вот простой пример
    abcd + dcba = (1000a + 100b + 10c + d) + (1000d + 100c + 10b + a) = 1001a + 110b + 110c + 1001d = 11(91a + 10b + 10c + 91d)
    Запись от wer1 размещена 26.10.2021 в 18:35 wer1 вне форума
  3. Старый комментарий
    Да, так тоже можно. Но здесь придётся вычислять S с помощью цифр заданного числа, ведь само S состоит из A+B, где B у нас неизвестное число. Алгоритм в этом случае будет сводиться к нахождению S с помощью суммы цифр разрядов, а не разности, как в посте. Но в целом, этот способ даже легче будет. Вот код набросал
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    #include <iostream>
    using namespace std;
    int Ten(int b) {
        int c = 1;
        for (int i = 0; i < b; i++) c = c * 10;
        return c;
    }
    int main() {
        int N, N2, sim = 0, k = 0, raz, sum;
        cin >> N; //само число
        N2 = N;
        //нахождение количества цифр в числе
        while (N2) {
            N2 = N2 / 10;
            sim++;
        }
        for (int i = 1; i <= (1+sim) / 2; i++) {
            sum = (N / Ten(sim - i) % 10 + ((N % Ten(i)) / Ten(i - 1)));
            k += sum * Ten(sim - i) + sum * Ten(i - 1);
        }
        if (sim % 2 != 0) k -= 2*(N / Ten(sim / 2) % 10)*Ten(sim/2); //вычитаем повторяющийся средний символ
        N2 = k-N;
        cout << N2;
    }
    Запись от kuppp размещена 26.10.2021 в 18:57 kuppp вне форума
  4. Старый комментарий
    А про сумму двух перевёрнутых чисел, делящейся на 11 не уверен. Это работает только с числами, в которых количество разрядов чётно
    Запись от kuppp размещена 26.10.2021 в 19:01 kuppp вне форума
  5. Старый комментарий
    О, эта магия чисел! Нет ничего более интересного и таинственного!
    Запись от MrCrown размещена 26.10.2021 в 22:23 MrCrown вне форума
 
Новые блоги и статьи
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru