10789. Простая частота
Строка содержит цифры (0-9) и
символы латинского алфавита (A-Z, a-z). Необходимо вычислить частоту каждого
символа (количество раз, которое он встречается) и вывести те символы, частоты
которых являются простыми числами.
Вход. Первая
строка содержит количество входных тестов T (0 < T < 201). Каждая из
следующих T строк содержит цифры и буквы латинского алфавита. Длины строк не
более 2001.
Выход. Для каждого теста вывести в
отдельной строке его номер и символы, частота которых есть простое число.
Символы выводить в лексикографическом порядке (по возрастанию их ASCII кодов).
Если не существует ни одного символа, частота которого является простым числом,
то вывести слово empty.
3
ABCC
AABBBBDDDDD
ABCDFFFF
Case 1: C
Case 2: AD
Case 3: empty
простые числа + сортировка за линейное
время
Сгенерируем массив primes длины MAX=2002, для которого primes[i] = 1 если i – простое число и primes[i] = 0 иначе. Используя
его можно эффективно проверять числа от 0 до 2001 на простоту. Заведем массив freq, ячейки которого будут содержать
частоту использования символов. Далее проверяем значения частот символов на
простоту и выводим их в лексикографическом порядке.
Пример
Рассмотрим второй тест. Частота
символа А равна 2, символа В – 4, символа D – 5. Поскольку простыми числами
являются только 2 и 5, выводить следует лишь символы A и D в порядке
возрастания их ASCII кодов.
Сгенерируем массив primes для
тестирования чисел на простоту. Для дальнейшего использования будем полагать,
что числа 0 и 1 являются сложными (primes[0]
= primes[1] = 0).
void gen_primes(void)
{
int i, j;
for(i = 0; i < MAX; i++) primes[i] =
1;
primes[0] = primes[1] = 0;
for(i = 2; i <= (int)sqrt(1.0*MAX); i++)
if (primes[i])
for(j = i; j * i < MAX; j++)
primes[i*j] = 0;
}
Ячейки массива freq[i] будут содержать частоту
использования символа с ASCII кодом i. Читаем входную строку, обнуляем
массив freq и заносим в него данные о частоте символов.
scanf("%s",&s);
memset(freq,0,sizeof(freq));
len = strlen(s);
for(j = 0; j < len; j++) freq[s[j]]++;
Выясним, существует ли хотя бы
один символ, частота которого есть простое число. Установим флаг-переменную found в 1, если такой символ существует.
found = 0;
for(j = '0'; j <= 'z'; j++)
if (primes[freq[j]])
{
found = 1; break;
}
Если found = 0, то выводим слово empty. Иначе следует перебрать все
символы от ‘0’ до ‘z’ (в лексикографическом порядке) и вывести те, частота
которых есть простое число.
if (!found) printf("Case
%d: empty\n",i+1);
else
{
printf("Case %d: ",i+1);
for(j = '0'; j
<= 'z'; j++)
if (primes[freq[j]]) printf("%c",j);
printf("\n");
}