Палиндром - это строка, которая читается одинаково как справа налево, так и слева направо.
На вход программы поступает набор больших латинских букв (не обязательно различных). Разрешается переставлять буквы, а также удалять некоторые буквы. Требуется из данных букв по указанным правилам составить палиндром наибольшей длины, а если таких палиндромов несколько, то выбрать первый из них в алфавитном порядке.
Входные данные
В первой строке входных данных содержится число ?
N
(1 <= ?
N
<= 100000). Во второй строке задается последовательность из ?
N
больших латинских букв (буквы записаны без пробелов).
Выходные данные
В единственной строке выходных данных выдайте искомый палиндром.
Группы тестов
25 баллов — (1 ≤ N ≤ 10) .
25 баллов — (1 ≤ N ≤ 1 000 ) .
50 баллов — полные ограничения.
Примеры
входные данные
3
AAB
выходные данные
ABA
входные данные
6
QAZQAZ
выходные данные
AQZZQA
входные данные
6
ABCDEF
выходные данные
A
C/C++
Палиндром c++ задача
#include
#include
using namespace std;
string palindromuse_optimaleous(string& str)
{
map library;
multimap numeric_lib;
//подсчет символов и их сортировка
for (auto& ch : str) library[ch]++;
for (auto& pa : library) numeric_lib.insert({ pa.second, pa.first });
//вычислитель длины палиндрома и используемых символов
library.clear();
char middle{};
bool chek_nechet = true;
uint32_t length{};
pair max_nechet {0,0};
for (auto& pa : numeric_lib)
{
if (chek_nechet && pa.first & 1) { max_nechet = { pa.second, pa.first }; length += pa.first; chek_nechet = false; continue; }
if (pa.first >= 2) {
library[pa.second] = pa.first - (pa.first & 1); length += pa.first - (pa.first & 1); continue;
}
}
//разделитель нечетного элемента для вставки всередину (если такой имеется)
if (max_nechet.second != 0)
{
if (max_nechet.second >=3) library[max_nechet.first] = max_nechet.second - 1;
middle = max_nechet.first;
}
//построитель строки палиндрома (половины)
string palindrom; palindrom.reserve(length+1);
for (auto& pa : library)
{
palindrom.append(pa.second/2, pa.first);
}
if (middle) palindrom.append(1,middle);
//дополнение половины строки до полной
copy(palindrom.rbegin() + (length & 1), palindrom.rend(), back_inserter(palindrom));
return palindrom;
}
int main()
{
string str;
cin >> str;
cout
#include
#include
#include
#include
#include
#include
using namespace std;
using box_t = map;
struct Compare {
using value_type = pair;
bool operator()(value_type& a, value_type& b) {
return a.second > b.second;
}
};
string create_palindrome(const box_t& box) {
using vec_t = vector;
vec_t even;
vec_t odd;
for (const auto& [key, value] : box) {
if (value & 1) odd.push_back({ key, value });
else even.push_back({ key, value });
}
Compare comp;
sort(odd.begin(), odd.end(), comp);
if (odd.size() > 1) {
for (auto it = odd.begin() + 1; it != odd.end(); ++it) {
const auto& [key, value] = *it;
if (value == 1) break;
else even.push_back({ key, value - 1 });
}
}
sort(even.begin(), even.end());
string line;
if (!even.empty()) {
for (const auto& [key, value] : even) {
line += string(value >> 1, key);
}
}
if (!odd.empty()) {
const auto& [key, value] = odd.at(0);
line += string(value, key);
}
if (!even.empty()) {
for (auto it = even.rbegin(); it != even.rend(); ++it) {
const auto& [key, value] = *it;
line += string(value >> 1, key);
}
}
return line;
}
int main() {
size_t n;
cin >> n;
string line;
line.reserve(n);
cin >> line;
box_t box;
for (auto ch : line) ++box[ch];
const auto palindrome = create_palindrome(box);
cout
ABCDEDCBA
AAABAAA
ABBBA
Вы можете заметить, что в палиндроме все буквы, кроме центральной, повторяются четное количество раз (2, 4, 6…), так как у каждой такой буквы есть зеркальная копия. Центральная буква существует только в палиндромах с нечетным количеством букв. Она используется нечетное количество раз (1, 3, 5…), и она такая одна.
В связи с этим есть смысл посчитать количество вхождений во входную строку каждой буквы. Найти первую по алфавиту букву, упоминаемую нечетное количество раз (назовем ее буквой Q, если она есть), а остальные нечетные исключить. Затем берем все буквы с четным количеством и выстраиваем по алфавиту, дублируя их половину их раз (N/2 раз для N-кратной буквы) по мере необходимости.
Пример: строка BBDAAAADCCCCCCDEFGG.
A — 4 раза
B — 2 раза
C — 6 раз
D — 3 раза
E — 1 раз
F — 1 раз
G — 2 раза
«Нечетные» буквы: D, E, F.
Берем D, отбрасываем E и F.
«Четные» буквы: A, B, C, G.
Выстраиваем их по алфавиту и дублируем N/2 раз: AABCCCG.
Затем вставляем нашу избранную «нечетную» букву D — 3 раза: DDD.
После этого берем четные буквы в обратном порядке: GCCCBAA.
Выходит палиндром: AABCCCGDDDGCCCBAA.
Язык C++ знаю не так хорошо, чтобы написать на нем эту программу.
AAABAAA
ABBBA
Вы можете заметить, что в палиндроме все буквы, кроме центральной, повторяются четное количество раз (2, 4, 6…), так как у каждой такой буквы есть зеркальная копия. Центральная буква существует только в палиндромах с нечетным количеством букв. Она используется нечетное количество раз (1, 3, 5…), и она такая одна.
В связи с этим есть смысл посчитать количество вхождений во входную строку каждой буквы. Найти первую по алфавиту букву, упоминаемую нечетное количество раз (назовем ее буквой Q, если она есть), а остальные нечетные исключить. Затем берем все буквы с четным количеством и выстраиваем по алфавиту, дублируя их половину их раз (N/2 раз для N-кратной буквы) по мере необходимости.
Пример: строка BBDAAAADCCCCCCDEFGG.
A — 4 раза
B — 2 раза
C — 6 раз
D — 3 раза
E — 1 раз
F — 1 раз
G — 2 раза
«Нечетные» буквы: D, E, F.
Берем D, отбрасываем E и F.
«Четные» буквы: A, B, C, G.
Выстраиваем их по алфавиту и дублируем N/2 раз: AABCCCG.
Затем вставляем нашу избранную «нечетную» букву D — 3 раза: DDD.
После этого берем четные буквы в обратном порядке: GCCCBAA.
Выходит палиндром: AABCCCGDDDGCCCBAA.
Язык C++ знаю не так хорошо, чтобы написать на нем эту программу.
тут исправленный алгоритм и подробное описание