2 / 2 / 0
Регистрация: 03.05.2020
Сообщений: 202

Найти количество делителей двух чисел

09.07.2021, 08:08. Показов 11778. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Дано натуральное число n. Подсчитайте количество таких пар чисел (a;b), что:

a и b — делители n;
a<b;
a и b — взаимно простые;
ab≤n.
Входные данные

Вводится натуральное число n≤108.

Выходные данные

Выведите количество таких пар.

Примеры
Ввод
10
Вывод
4
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.07.2021, 08:08
Ответы с готовыми решениями:

С клавиатуры вводится N чисел. Найти количество чисел, у которых количество делителей четное число
С клавиатуры вводится N чисел. Найти количество чисел, у которых количество делителей четное число.

Найти количество чисел имеющих четное количество делителей
найдите количество от 1 до n которые имеют четное количество делителей Добавлено через 31 секунду вход 10 выход 7

Найти количество чисел имеющих четное количество делителей
Дано целое число n. Найдите кол-во чисел от 1 до n, которые имеют четное кол-во делителей. Формат входных данных: В первой строке...

30
6 / 5 / 1
Регистрация: 19.07.2021
Сообщений: 1
19.07.2021, 11:09
Лучший ответ Сообщение было отмечено dmitrii2000 как решение

Решение

Студворк — интернет-сервис помощи студентам
Здравствуйте, Catstail, ваше решение почти правильное, я его лишь доработал под данное условие.

Во-первых, ab≤n, а не ab<n.

Во-вторых, условие задачи не очень правильное по моему мнению. 1 считается за простое число, хотя это не так. Таким образом получаем 4 пары чисел: (1, 10);(1, 5);(1, 5);(2, 5).

Учитывая эти факторы, выкладываю доработанное решение:

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
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
int gcd(int a, int b)
{
    int tmp;
    while(b != 0)
    {
        tmp=a%b;
        a=b;
        b=tmp;
    }
    return a;
}
 
int main()
{
    vector<int> factors;
    int n,k,sz,a,b,c;
    cin >> n;
    
    k=1;
    while (k*k<=n)
    {
        if (n%k==0)
        {
            factors.push_back(k);
            if (n/k != k) factors.push_back(n/k);
        }
        k++;
    }
    
    sort(begin(factors), std::end(factors));
 
    sz=factors.size();
    c=0;
    
    for (int i=0; i<sz-1; i++)
        for (int j=i+1; j<sz; j++)
        {
            a=factors[i];
            b=factors[j];
            if ((gcd(a,b)==1) && (a*b<=n)) 
            {
                c++;
            }
        }    
    
    cout << c;
 
    return 0;
}
P.s. Первый раз пишу на данном форуме, если что-то не так, извините.
5
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
19.07.2021, 12:47
Цитата Сообщение от mat_bub Посмотреть сообщение
Во-вторых, условие задачи не очень правильное по моему мнению. 1 считается за простое число, хотя это не так.
А в задании ничего и нет про простые числа. Там про взаимно простые, а 1 действительно считается взаимно простым с любым числом.
0
1 / 1 / 0
Регистрация: 10.02.2022
Сообщений: 2
06.07.2024, 22:36
1. разложим число n на простые множители.
получится разложение вида:

https://www.cyberforum.ru/cgi-bin/latex.cgi?\small \mathit{\mathbf{n = {{p}_{1}}^{{a}_{1}}\cdot {{p}_{2}}^{{a}_{2}}\cdot...\cdot{ {p}_{s}}^{{a}_{s}}}}

2. Пользуясь комбинаторикой я вывел формулу для ответа:

https://www.cyberforum.ru/cgi-bin/latex.cgi?\small \mathit{\mathbf{ans\:=\:  \frac{(2{a}_{1}\: +\: 1)\cdot (2{a}_{2}\: +\: 1)\cdot\: ...\: \cdot (2{a}_{s}\: +\: 1)\: -\: 1}{2}}}

т.е. остаётся только перебрать все простые делители и посчитать ответ.
мой код:
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
#include <iostream>
#include <ext/pb_ds/assoc_container.hpp>
 
using namespace std;
using ll = long long;
 
int main() {
    ll n;
    cin >> n;
    set<ll> dels;
    map<ll, ll> cntd;
    ll f = 2;
    while(f * f <= n){
        if(n % f == 0){
            n /= f;
            dels.insert(f);
            cntd[f]++;
        }
        else f++;
    }
    if(n - 1) {
        dels.insert(n);
        cntd[n]++;
    }
    ll fi = 1;
    for(auto d : dels){
        fi *= (2 * cntd[d] + 1);
    }
    fi = (fi - 1)/ 2;
    cout << fi;
}
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,345
07.07.2024, 06:34
Цитата Сообщение от Iltner A Посмотреть сообщение
Пользуясь комбинаторикой я вывел формулу для ответа:
Формула для ответа - (a1+1)(a2+1)...(as+1) - здесь уже не раз приводилась (Поиск подходящих чисел). Формула фактически очевидным образом вытекает из факторизации числа. Поэтому как и зачем вы умудрились запихать в свой вариант эти странные умножения и деления на 2 - не ясно.

Более того, по вашей формуле получается, что число 20 (= 22*51) имеет 7 делителей (=((2*2+1)(2*1+1)-1)/2). Но правильный ответ - 6 (=(2+1)(1+1)).
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
07.07.2024, 10:01
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Более того, по вашей формуле получается, что число 20 (= 22*51) имеет 7 делителей (=((2*2+1)(2*1+1)-1)/2). Но правильный ответ - 6 (=(2+1)(1+1)).
Возможно вы решаете разные задачи. Для числа 20 число делителей действительно 6 (1, 2, 4, 5, 10, 20), но количество пар, удовлетворяющих условиям исходной задачи на самом деле 7: (1, 2), (1, 4), (1, 5), (1, 10), (1, 20), (2, 5), (4, 5).
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,345
07.07.2024, 18:09
Цитата Сообщение от grizlik78 Посмотреть сообщение
Возможно вы решаете разные задачи.
Да, вы правы. Я почему-то не понял, что формула Iltner A - ответ для исходной задачи, а не просто для количества делителей.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,345
24.08.2024, 01:23
Для начала уберем требование a<b из условия задачи. Пусть нас интересует P(x) - количество таких пар (a, b) для числа x, в котором (a, b) и (b, a) считаются разными парами. Обратите внимание, что теперь пара (1, 1) тоже учитывается и это единственная "симметричная" пара.

1. Взглянем на искомую функцию P(x).

Пусть y и z - взаимно просты (эквивалентно: простые факторизации y и z не содержат одинаковых факторов).

Пусть взаимно простая пара (a, b) входит в P(y), а взаимно простая пара (c, d) входит в P(z). Очевидно, что ac|yz (делит) и bd|yz.
Ясно также, что числа ac и bd - взаимно просты. Действительно, если, скажем, c и b имеют общий простой фактор, то это противоречит взаимной простоте y и z.
То есть пара (ac, bd) будет входить в P(yz).

В другую сторону, пусть пара (e, f) входит в P(yz). Факторизация e будет содержать только простые факторы чисел y и z. Обозначим произведение первых через a, а вторых - через c, т.е. e=ac. Аналогичным образом разложим f в произведение f=bd. Мы получим пары (a, b) и (c, d). Понятно, что и a, и b делит y. При этом общих простых факторов у a и b нет (в противном случае e и f не были бы взаимно простыми), что значит, что a и b - взаимно простые. То есть (a, b) входит в P(y). Аналогичным образом: (c, d) входит в P(z).

Несложно видеть, что таким образом мы получили взаимно однозначное соответствие между каждой комбинацией пар (a, b) из P(y) и (с, d) из P(z) и парой (ac, bd) из P(yz). Из этого следует мультипликативность функции P(x), то есть для взаимно простых y и z выполняется P(yz) = P(y)P(z)

2. Пусть x=pn, где p - простое число. Чему равно P(x)? Очевидно, что это будет пара (1, 1) и всевозможные пары вида (1, pk) и (pk, 1) для k=1..n. Общее количество таких пар равно 2n+1.

3. Так как функция P(x) мультипликативна, для любого числа x, факторизация которого имеет вид pkqlrm..., функция P(x) будет равна (2k+1)(2l+1)(2m+1)...

4. А теперь вернем требование a<b в условие задачи. Тут же из общего набора допустимых пар исчезнет пара (1, 1), а из остального набора допустимых пар исчезнут пары-нарушители, которых будет ровно половина.

Это и даст нам искомую формулу: для числа x=pkqlrm... ответ задачи равен ((2k+1)(2l+1)(2m+1)... - 1)/2

P.S. На шаге 3 видно, что P(x) равна количеству делителей x2.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,345
24.08.2024, 19:59
P.P.S. Интересно было бы найти какой-то более-менее несложный способ взаимно однозначного отображения между такими парами для x и делителями x2. Это привело бы к более "конструктивному" (и потому более наглядному) выводу формулы из пункта 3. Навскидку у меня не получилось найти такое отображение.
0
0 / 0 / 0
Регистрация: 26.08.2024
Сообщений: 2
26.08.2024, 22:00
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 <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <numeric>
 
unsigned gcd(unsigned a, unsigned b)
{
  if (!a || !b) return a + b;
  while (a != b) if (a > b) a -= b; else b -= a;
  return a; 
}
 
int main() {
    long long n;
    std::cin >> n;
 
    std::vector<long long> divisors;
    for (long long i = 1; i * i <= n; ++i) {
        if (n % i == 0) {
            divisors.push_back(i);
            if (i != n / i) {
                divisors.push_back(n / i);
            }
        }
    }
 
    int count = 0;
 
    for (size_t i = 0; i < divisors.size(); ++i) {
        for (size_t j = i + 1; j < divisors.size(); ++j) {
            long long a = divisors[i];
            long long b = divisors[j];
 
            if (a < b && gcd(a, b) == 1 && a * b <= n) {
                count++;
            }
        }
    }
 
    std::cout << count << std::endl;
 
    return 0;
}
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,345
26.08.2024, 22:35
Правильное решение уже приводилось в аналогичной теме: Найти количество делителей двух чисел
0
Нарушитель
Эксперт функциональных языков программированияЭксперт С++
6319 / 3044 / 1054
Регистрация: 01.06.2021
Сообщений: 11,625
26.08.2024, 23:18
Цитата Сообщение от Runer543221 Посмотреть сообщение
C++
1
#include <numeric>
ну раз подключаешь это, то зачем всё это

Цитата Сообщение от Runer543221 Посмотреть сообщение
C++
1
2
3
4
5
6
unsigned gcd(unsigned a, unsigned b)
{
if (!a || !b) return a + b;
while (a != b) if (a > b) a -= b; else b -= a;
return a;
}
просто используй std::gcd из <numeric>

тем более, у тебя один из самых медленных алгоритмов для вычисления gcd на основе вычитаний. Можно же использовать алгоритм на основе %.

Хотя, в код не вникал и, возможно, там всё нужно менять...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.08.2024, 23:18

Для каждого числа найти количество его делителей и определить общее количество простых чисел в последовательности
С клавиатуры вводится последовательность целых чисел, 0 - конец этой последовательности. Для каждого числа найти количество его делителей и...

Найти количество делителей каждого из целых чисел от a до b на с++
Найти количество делителей каждого из целых чисел от a до b на с++ (не ругайте только начал изучать ) заранее спасибо

Найти количество положительных делителей произведения 10 чисел
Десять математиков летели на воздушном шаре над Тихим океаном. Когда они пересекали экватор, они решили отметить это событие и открыли...

Найти количество делителей каждого из целых чисел от 120 до 140
Найти количество делителей каждого из целых чисел от 120 до 140.

Вводится последовательность из N целых чисел. Найти количество двух- и количество трех разрядных чисел в последовательн
Вводится последовательность из N целых чисел. Найти количество двух- и количество трех разрядных чисел в последовательности (функцией...


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

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Опции темы

Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru