Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
0 / 0 / 0
Регистрация: 11.12.2018
Сообщений: 21

Получить все числа, в разложении которых на простые множители, каждый множитель входит ровно два раза

11.12.2018, 23:04. Показов 2732. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Дано натуральное число n. Получить все числа меньшие n, в разложении которых на простые множители, каждый множитель входит ровно два раза. C++
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.12.2018, 23:04
Ответы с готовыми решениями:

Подпрограмма: найти числа, в разложении которых на простые множители присутствует 2 раза число 13
1 - найти 100 первых чисел, в разложении которых на простые множители присутствует ровно два раза число 13, используя подпрограмму,...

Проверить верно ли, что в разложении числа на простые множители все множители различны
2. 1. Дано натуральное число n. Проверить верно ли, что в разложении этого числа на простые множители, все множители различны. С++

Встречаются ли в разложении числа на простые множители одинаковые множители?
и ещё эта Программа не получается:-(помогите пожалуйста,мне практику надо сдать:(..написать программу,которая проверяет встречаются ли в...

9
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
12.12.2018, 00:03
Простое решение в лоб. Возможно есть более красивые и оптимальные.

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;
 
bool check(long number) {
    bool dividers_is_paired = (number >= 4);
    long temp = number;
 
    for (long i = 2; (i * i < number) && dividers_is_paired; i++) {
        long count = 0;
        while (temp % i == 0) {
            temp /= i;
            count++;
        }
 
        dividers_is_paired = dividers_is_paired && ((count == 0) || (count == 2));
    }
 
    return (dividers_is_paired && (temp == 1));
}
 
int main() {
    long n;
    cin >> n;
 
    for (long i = 1; i < n; i++) {
        if (check(i)) {
            cout << i << endl;
        }
    }
 
    return 0;
}
0
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
12.12.2018, 01:19
rom_kach, здравствуйте! Вот еще такой вариант:

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
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream> 
#include <algorithm> 
#include <iterator> 
#include <map>
 
    using namespace std;
 
int main() {
    int n, k, tmp;
    bool flag;
    cout << "Enter a number:\n";
    cout << "n = ";
    cin >> n;
    cout << "Output of the program:\n";
    for (int i = 2; i < n; i++) {
        map < int, int > mp;
        flag = true;
        k = 2;
        tmp = i;
        while (k <= tmp) {
            if (tmp % k == 0) {
                tmp /= k;
                mp[k]++;
            } else k++;
        }
        for (auto it = mp.begin(); it != mp.end(); ++it) {
            if (it->second != 2) {
                flag = false;
                break;
            }
        }
        if (flag) {
            cout << i << " => ";
            for (auto it = mp.begin(); it != mp.end(); ++it) {
                cout << it->first << " ";
                cout << it->first << " ";
            }
            mp.clear();
            cout << "\n";
        }
    }
    system("pause");
    return 0;
}
P.S. Немного исправил концовку предыдущего кода. Этот код обновленный вариант предыдущего.
1
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
12.12.2018, 01:21
Господа! Если не лениться и приложить на секунду палец к носу, то совершенно очевидно, что требуемые числа обязаны быть полными квадратами. Поэтому даже не стоит эти квадраты перебирать. А перебирать надо
C++
1
2
for(k=2; k*k <= n; k++) 
  // и вот здесь проверять, есть ли у k больше одного простого делителя
Или вы считаете ТС настолько тупыми и некчемными людьми, что с ними и смысла нет говорить об алгоритмах, чуть-чуть отличающимися от грубого перебора?
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
12.12.2018, 04:44
Цитата Сообщение от Байт Посмотреть сообщение
Или вы считаете ТС настолько тупыми и некчемными людьми, что с ними и смысла нет говорить об алгоритмах, чуть-чуть отличающимися от грубого перебора?
А вы считаете тут всех умными, как вы сами? Часто восхищаюсь вашими идеями и мечтаю хотя бы приблизиться к вашему уровню знаний. Чтобы выдавать хорошие решения, нужно уметь думать (не уверен, что мне это дано) и думать (что часто бывает лень), вот и получаются такие грубые наброски, не выдерживающие никакой критики.

Цитата Сообщение от Байт Посмотреть сообщение
числа обязаны быть полными квадратами
Ценное замечание, благодаря которому можно перейти к алгоритму на порядок меньшей сложности. Долго пытался вывести формулы, но результаты анализа и измерений не совпадали, поэтому просто приведу цифры.

Сравнение количества действий до и после оптимизации
До оптимизации (n = 100 000, для большего значения результатов не дождался):
Code
1
2
Количество повторений цикла: 503105454
Количество делений: 184458
После оптимизации (n = 100 000):
Code
1
2
Количество повторений цикла: 14628
Количество делений: 497
После оптимизации (n = 1 000 000 000, алгоритм с легкостью справился и с этим числом):
Code
1
2
Количество повторений цикла: 80853884
Количество делений: 59897


Программа с учетом замечаний
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;
 
bool check(long number) {
    bool is_suitable = (number >= 2);
 
    for (long i = 2; (i <= number) && is_suitable; i++) {
        long count = 0;
        while (number % i == 0) {
            number /= i;
            if (++count > 1) {
                is_suitable = false;
                break;
            }
        }
    }
 
    return is_suitable;
}
 
int main() {
    long n;
    cin >> n;
 
    for (long i = 1; i * i < n; i++) {
        if (check(i)) {
            cout << i * i << endl;
        }
    }
 
    return 0;
}
2
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
12.12.2018, 12:48
valen10, приятно, когда твои слова падают на плодородную почву.
Цитата Сообщение от valen10 Посмотреть сообщение
нужно уметь думать (не уверен, что мне это дано)
Скромность - это наше все
Спасибо за интересное исследование.
Цитата Сообщение от valen10 Посмотреть сообщение
А вы считаете тут всех умными, как вы сами?
Увы, нет. Но по возможности пытаюсь сделать хоть на микрон умнее. Чем больше умных людей вокруг, тем веселее жить!

Добавлено через 25 минут
valen10, посмотрел ваш код. Немножко косметики (на эффективность практически не влияет)
C++
1
2
3
4
5
6
7
8
9
10
bool check(long number) {
    for (long i = 2; i <= number/2; i++) {
        long count = 0;
        while (number % i == 0) {
            number /= i;
            if (++count > 1) return false;
        }
    }
    return true;
}
Кажется, условие конца цикла (i<=number/2) можно сделать еще жестче, типа i*i <= number, но чего-то никак не могу сообразить...
1
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
12.12.2018, 13:49
Лучший ответ Сообщение было отмечено Nishen как решение

Решение

rom_kach, вот оптимизированный вариант с учетом всех пожеланий:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream> 
#include <cmath> 
#include <algorithm> 
#include <iterator> 
#include <map>
 
    using namespace std;
 
int main() {
    int n, k, tmp;
    bool flag;
    cout << "Enter a number:\n";
    cout << "n = ";
    cin >> n;
    cout << "Output of the program:\n";
    for (int i = 2; i < n; i++) {
        map<int, int> mp;
        flag = true;
        k = 2;
        tmp = i;
        while (k * k <= tmp) {
            if (tmp % k == 0) {
                tmp /= k;
                mp[k]++;
            } else k++;
        }
        mp[tmp]++;
        for (auto it = mp.begin(); it != mp.end(); ++it) {
            if (it->second != 2) {
                flag = false;
                break;
            }
        }
        if (flag) {
            cout << i << " => ";
            for (auto it = mp.begin(); it != mp.end(); ++it) {
                cout << it->first << " ";
                cout << it->first << " ";
            }
            mp.clear();
            cout << "\n";
        }
    }
    system("pause");
    return 0;
}
1
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
12.12.2018, 18:07
Лучший ответ Сообщение было отмечено Nishen как решение

Решение

Цитата Сообщение от Байт Посмотреть сообщение
Немножко косметики (на эффективность практически не влияет)
Тоже думал, что не влияет, и в условие можно i*i поставить, но... Просто поделюсь впечатлениями. Возможно, эта информация никого не удивит, для меня она оказалась несколько неожиданной.

На первый взгляд, простое сравнение разменивается на более тяжелую операцию умножения. Поверхностный анализ и остаточные знания о предсказаниях перехода и спекулятивном исполнении шепчут "не делай так". Но руки, как говорится, чешутся. Оставив тщетные попытки осознать происходящее, перешел к действиям. После замены i на https://www.cyberforum.ru/cgi-bin/latex.cgi?i^2 для n=1000000000 сократилось число повторений цикла (80853884 -> 1084752) и число делений (72295* -> 53072).

(*) В предыдущем посте была ошибка с этим числом, не учитывалось деление, приводящее к выходу из цикла.
Но это всего лишь цифры, которые лично мне сложно осознать: их не потрогать, не сравнить с повседневным опытом. Насколько 80853884 хуже 1084752? Что можно успеть сделать за время сотен тысяч таких повторов? Непонятно. Поэтому, пока еще жива во мне любопытная Варвара, сделаю эти наивные измерения.

Глупые циклы vs Хитрое умножение

Было подготовлено несколько вариантов программы с https://www.cyberforum.ru/cgi-bin/latex.cgi?i и https://www.cyberforum.ru/cgi-bin/latex.cgi?i^2 в условии, x86 и x86_64, оптимизация -O2 и -O3. По 10 повторений каждого варианта для числа https://www.cyberforum.ru/cgi-bin/latex.cgi?n = 10^{11}. Время работы измерялось командой time, средние значения занесены в таблицу.

Для желающих повторить измерения оставлю все используемые тексты.
Исходный код программы
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
33
34
35
36
37
38
39
40
41
42
43
44
45
//#define MODE 2
#include <iostream>
using namespace std;
 
//long long div_count = 0;
//long long cmp_count = 0;
 
bool check(long long number) {
#if MODE == 1
    for (long long i = 2; i <= number; i++) {
#elif MODE == 2
    for (long long i = 2; i * i <= number; i++) {
#endif
//        cmp_count++;
        long long count = 0;
        while (number % i == 0) {
//            div_count++;
            number /= i;
            if (++count > 1) {
                return false;
            }
        }
    }
 
    return true;
}
 
int main() {
    long long n = 100000000000;
//    cin >> n;
 
    long long count = 0;
    for (long long i = 1; i * i < n; i++) {
        if (check(i)) {
            count++;
//            cout << i * i << endl;
        }
    }
    cout << count << endl;
 
//    cout << "cmp: " << cmp_count << endl;
//    cout << "div: " << div_count << endl;
 
    return 0;
}

build.sh
Bash
1
2
3
4
5
6
7
8
9
#!/bin/bash
g++ -o test_1_o2_x32 -m32 -O2 -DMODE=1 Source.cpp
g++ -o test_1_o3_x32 -m32 -O3 -DMODE=1 Source.cpp
g++ -o test_1_o2_x64 -m64 -O2 -DMODE=1 Source.cpp
g++ -o test_1_o3_x64 -m64 -O3 -DMODE=1 Source.cpp
g++ -o test_2_o2_x32 -m32 -O2 -DMODE=2 Source.cpp
g++ -o test_2_o3_x32 -m32 -O3 -DMODE=2 Source.cpp
g++ -o test_2_o2_x64 -m64 -O2 -DMODE=2 Source.cpp
g++ -o test_2_o3_x64 -m64 -O3 -DMODE=2 Source.cpp

test.sh
Bash
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
for exe in test_*
do
    for i in 1 2 3 4 5 6 7 8 9 10
    do
        echo "=== Test ($exe) #$i =============================="
        time "./$exe"
        echo
    done
done


Краткие итоги (в секундах). x86 почему-то опережает x86_64. Что я делаю не так?!
 O2 x86O3 x86O2 x86_64O3 x86_64
https://www.cyberforum.ru/cgi-bin/latex.cgi?i34,237834,245641,248941,2519
https://www.cyberforum.ru/cgi-bin/latex.cgi?i^2 0,17100,17050,18930,1889

Ничего существенного за это время не сделаешь, но разница ощутимая. Незначительная на первый взгляд оптимизация при больших значениях n дает значительный выигрыш по времени. Байт, ваше решение вновь занимает первое место. С вашими комментариями мир и правда становится чуточку лучше (или на микрон умнее? Уже запутался).
1
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
12.12.2018, 18:58
Цитата Сообщение от valen10 Посмотреть сообщение
x86 почему-то опережает x86_64. Что я делаю не так?!
Не знаю. По идее этого быть не должно. Но вопросами сравнительного анализа такого рода я не занимался.
Ну, то что I2 эффективнее, чем I - это очевидно. Не ожидал, правда, что настолько.
А вот интересно, результат-то (count) всюду одинаковый?
И еще вопрос совсем уж дурацкий. Вы не могли данные перепутать?
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
13.12.2018, 00:01
Цитата Сообщение от Байт Посмотреть сообщение
А вот интересно, результат-то (count) всюду одинаковый?
Одинаковый, везде число 192256 получилось.

Цитата Сообщение от Байт Посмотреть сообщение
Вы не могли данные перепутать?
Мог конечно. Но тут вроде все имена в скриптах прописаны, больше ничего вручную не вводится. Вот копипаста части результатов для первых двух вариантов.

Кликните здесь для просмотра всего текста
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
=== Test (test_1_o2_x32) #1 ==============================
192256
 
real    0m34,297s
user    0m34,236s
sys     0m0,004s
 
=== Test (test_1_o2_x64) #1 ==============================
192256
 
real    0m41,231s
user    0m41,213s
sys     0m0,000s


Немного поискал информацию о таком поведении. Зависит от случая к случаю. Чтобы понять причины, там предлагают выполнить дизассемблирование и разбираться на уровне команд. Это все конечно интересно, но тема не моя. Поэтому, думаю, это исследование можно закончить. Если вы конечно не придумаете новую оптимизацию
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.12.2018, 00:01
Помогаю со студенческими работами здесь

Проверить, входит ли в запись числа ровно два раза цифра 5
Дано целое число n, удовлетворяющее условию 0 &lt; |n| ≤ 2 · 109. Проверить, входит ли в запись числа n цифра 5 ровно два раза.

Определение степени числа 3 в разложении на простые множители
Определить в какой степени входит число 3 в разложение на простые множители натурального числа n

Найти количество различных простых множителей в разложении числа на простые множители.
1. Составить программу, которая находит количество различных простых множителей в разложении числа на простые множители.

Определить, в какой степени входит число 3 в разложение на простые множители натурального числа п
Определить, в какой степени входит число 3 в разложение на простые множители натурального числа п

Получить два множества: все простые числа из этого диапазона и все остальные
Задача: Дано множество целых числа от 8 до 22. Получить два множества: все простые числа из этого диапазона и все остальные. Program...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru