Матч
396, Строка DNA (DNAString)
Дивизион 2,
Уровень 2; Дивизион 1, Уровень 1
Строка длины L называется
периодической, если ее i-ый символ
равен (i + p)-ому для всех i от 0 до
L – p – 1 включительно. Например,
строки “CATCATC”,“CATCAT”, “ACTAC” и “ACT” являются периодическими с периодом
3.
Составим строку, содержащую
конкатенацию всех строк из массива dna. В ней необходимо совершить наименьшее
количество замен, после выполнения которых строка будет иметь период, не
больший maxPeriod. Заменой называется
изменение одного символа на другой.
Класс: DNAString
Метод: int
minChanges(int maxPeriod, vector<string> dna)
Ограничения: dna содержит от 1 до 50 элементов, dna[i]
содержит от 1 до 50 символов ‘A’, ‘C’, ‘G’, ‘T’, 1 £ maxPeriod £ n, где n равно числу символов в
объединенной строке.
Вход. Число maxPeriod и массив строк
dna.
Выход. Наименьшее количество замен, после выполнения которых строка
будет иметь период, не больший maxPeriod.
Пример входа
maxPeriod |
dna |
3 |
{"ATAGATA"} |
1 |
{"AAAATTTCCG"} |
12 |
{"ACGTATAGCATGACA","ACAGATATTATG","ACAGATGTAGCAGTA","ACCA","GAC"} |
Пример выхода
1
6
20
РЕШЕНИЕ
обработка строк
Объединим строки массива dna при
помощи функции accumulate.
Предположим, что мы хотим
получить строку с периодом 1. Тогда все символы должны быть одинаковы. Найдем
символ, чаще всего встречающийся в строке, и заменим на него все остальные
символы.
Пусть требуется получить строку с
периодом 2. Тогда символы, стоящие на четных местах, и символы на нечетных
местах должны быть одинаковыми. В четных и нечетных позициях меняем символы на
те, которые чаще всего в них встречаются.
Аналогично поступаем при
получении строки с периодом i.
Для решения задачи перебираем все
возможные значения периода i (1 £ i £ maxPeriod). Для каждого
значения периода i вычисляем наименьшее
число символов, которое следует изменить, в переменной add. Среди всех полученных значений add для разных i находим
наименьшее, которое и будет результатом.
ПРОГРАММА
#include <cstdio>
#include <string>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;
int d[256];
class DNAString
{
public:
int minChanges(int
maxPeriod, vector<string> dna)
{
string s = accumulate(dna.begin(),dna.end(),string());
int add, i, j, k, res = s.size(), n =
s.size();
for(i = 1; i <= maxPeriod; i++)
{
for(add = j = 0; j < i; j++)
{
memset(d,0,sizeof(d));
for(k = j; k < n; k += i) d[(int)s[k]]++;
add = accumulate(d,d+256,add) - *max_element(d, d + 256);
}
if (add < res) res = add;
}
return res;
}
};