Матч
261, Статистика простых чисел (PrimeStatistics)
Дивизион 2, Уровень
2; Дивизион 1, Уровень 1
Заданы три целых числа: lowerBound,
upperBound
и modulo.
Находятся остатки всех простых чисел, лежащих в промежутке [lowerBound,
upperBound]
при делении на modulo. Необходимо найти значение чаще всего встречаемого
остатка. Если остатков существует несколько, то вывести наименьший.
Класс: PrimeStatistics
Метод: int
mostCommonRemainder(int lowerBound, int upperBound,
int modulo)
Ограничения:
1 £ lowerBound, upperBound £ 20000,
lowerBound £ upperBound, 2 £ modulo £ 1000.
Вход. Три целых числа: lowerBound, upperBound и modulo.
Выход. Остаток, который чаще всего встречается при делении простых
чисел из промежутка [lowerBound, upperBound] на modulo.
Пример входа
lowerBound |
upperBound |
modulo |
3 |
14 |
5 |
3 |
33 |
1000 |
25 |
27 |
17 |
Пример выхода
3
3
0
РЕШЕНИЕ
простые числа
При помощи решета Эратосфена
генерируем простые числа от 1 до upperBound
в массиве primes. Следует отметить, что единица не является простым числом.
Вычисляем остатки от деления всех чисел от lowerBound
до upperBound на modulo и заносим их количество в массив rem: число остатков, равных
i, содержится в rem[i]. Находим максимальный элемент в
массиве rem, его индекс является искомым значением остатка.
Рассмотрим первый пример.
Построим массив primes для значений от lowerBound
= 3 до upperBound = 14 и найдем
остатки от деления простых чисел на modulo
= 5.
i |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
primes[i] |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
primes[i] % modulo |
- |
- |
3 |
- |
0 |
- |
2 |
- |
- |
- |
1 |
- |
3 |
- |
В массиве rem подсчитываем количество
остатков primes[i] % modulo для простых i.
i |
0 |
1 |
2 |
3 |
4 |
rem[i] |
1 |
1 |
1 |
2 |
0 |
Максимальное значение массива rem
равно 2, чаще всего встречается остаток 3.
ПРОГРАММА
#include <stdio.h>
#include <memory.h>
int max, res, i, j;
int rem[1001], primes[200001];
class PrimeStatistics
{
public:
int mostCommonRemainder(int
lowerBound, int upperBound, int modulo)
{
for(i = 0; i <= upperBound; i++) primes[i]
= 1;
primes[1] = 0;
for(i = 2; i * i <= upperBound; i++)
if (primes[i])
for(j = i; j * i <= upperBound; j++)
primes[i * j] = 0;
memset(rem,0,sizeof(rem));
for(i = lowerBound; i <= upperBound;
i++)
if (primes[i]) rem[i%modulo]++;
for(max = i = 0; i < modulo; i++)
if (rem[i] > max) res = i,
max=rem[i];
return res;
}
};