Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.78/40: Рейтинг темы: голосов - 40, средняя оценка - 4.78
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337

Переставить буквы строки так, чтобы получился палиндром

07.08.2017, 22:03. Показов 8315. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, уважаемые пользователи прекрасного форума! Столкнулся с небольшой проблемой оптимизации при сдаче несложной задачи (все 0,1 секунды не хватает((). Прошу всех, кто знает ответ, помочь в улучшении представленного ниже кода.

Условие:

На вход программы подаются заглавные латинские буквы, ввод этих символов заканчивается точкой. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять, можно ли переставить эти буквы так, чтобы получился палиндром (палиндром читается одинаково слева направо и справа налево). Программа должна вывести ответ «YES» или «NO», а в случае ответа «YES» – еще и сам полученный палиндром (первый в алфавитном порядке).

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

На вход программы подаются заглавные латинские буквы, ввод этих символов заканчивается точкой.

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

Программа должна вывести ответ «YES» или «NO», а в случае ответа «YES» – еще и сам полученный палиндром (первый в алфавитном порядке).

Примеры:

Входные данные:
GAANN.

Выходные данные:
YES
ANGNA

Мое решение:

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
#include <bits/stdc++.h>
 
using namespace std;
 
bool IsPal(string str)
{
    string tmp;
    tmp = str;
    reverse(str.begin(), str.end());
    if (tmp == str)
        return true;
    return false;
}
 
int main()
{
    string str;
    bool flag = false;
    getline(cin, str);
    str.pop_back();
    sort(str.begin(), str.end());
    do
    {
        if (IsPal(str))
        {
            cout << "YES" << '\n' << str << '\n';
            flag = true;
            break;
        }
    } while (next_permutation(str.begin(), str.end()));
    if (!flag)
        cout << "NO" << endl;
    system("pause");
    return 0;
}
P.S. Сам читаю книгу про оптимизацию при сдаче олимпиадных задач, но пока кроме встроенных функций и нового заголовка #include <bits/stdc++.h> ничего дельного не нашел. Очень надеюсь на вашу помощь!

Добавлено через 4 минуты
Может передавать строку по ссылке? Но где именно внести изменения? Кто-нибудь знает?

Добавлено через 5 минут
Может просто переделать функцию из IsPal() с использованием указателей? Ума не приложу как это сделать

Добавлено через 8 минут
Пробовал менять функцию проверки строки на палиндромность. В нескольких тестах всего 0,007 секунды не хватает теперь Какой последний штрих можно применить к коду?

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
#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    string str;
    bool flag = false;
    getline(cin, str);
    str.pop_back();
    sort(str.begin(), str.end());
    do
    {
        if (str == string(str.rbegin(), str.rend()))
        {
            cout << "YES" << '\n' << str << '\n';
            flag = true;
            break;
        }
    } while (next_permutation(str.begin(), str.end()));
    if (!flag)
        cout << "NO" << endl;
    system("pause");
    return 0;
}
Добавлено через 16 минут
Может использовать другой цикл? Ума не приложу какой из них работает быстрее.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.08.2017, 22:03
Ответы с готовыми решениями:

Из данной строки удалите наименьшее количество символов, так, чтобы получился палиндром
Срочно до утра нужно построить несколько алгоритмов на С++. Кто может помогите! Вот задания: 4.Из данной строки удалите наименьшее...

Требуется изменить порядок букв так, чтобы получился палиндром
Восстановление палиндрома Задано слово, состоящее из маленьких латинских букв. Требуется изменить порядок букв так, чтобы получился...

Заданы две строки. Можно ли переставить буквы в одном из слов так, чтобы слова стали одинаковыми?
F. Заданы две строки А и В. Можно ли переставить буквы в одном из слов так, чтобы слова стали одинаковыми? Выведите &quot;Yes&quot;, если...

36
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 16:15
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от easybudda Посмотреть сообщение
Вопрос с нечётным количеством бук
Главное идея, тривиально допилить же. Никаких нечетных, откусываем всегда по паре, если пара неравна - пробуем первую букву из нее считать за центральную и со второй продолжаем откусывать. Если уже есть кандидат на центральную а нашли еще одного - сразу NO. Имхо все случаи рассмотрел.

ЗЫ и конечно эрейзить ничего не надо - вообще работать не со строками а с массивами чаров.

Добавлено через 11 минут
UPD а в середину засовывать и все переписывать тоже не надо. Можно сформировать 2 строки результата - прямую и обратную часть, и выводить подряд - прямую, среднюю букву (если он есть) - обратную прямо в принте, не гоняя символы по памяти.
0
1719 / 568 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
08.08.2017, 16:15
_Ivana, а если кусать не по паре, а сразу находить количество одинаковых букв, а уж потом проверять найденное количество на четность. Так на мой взгляд будет легче.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 16:21
мановар, если не стоит задача
Цитата Сообщение от Fixer_84 Посмотреть сообщение
в случае ответа «YES» – еще и сам полученный палиндром (первый в алфавитном порядке)
- тогда и огород не надо городить. Но она стоит же

Добавлено через 2 минуты
Но можете и через мап, перебирая ключи в порядке возрастания и смотря на накопленное количество - будет тот же алгоритм, но на серьезных структурах данных, больше по размеру кода и выполняться медленнее
0
1719 / 568 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
08.08.2017, 16:28
Цитата Сообщение от _Ivana Посмотреть сообщение
Но она стоит же
Находить то будем после сортировки естественно, как Вы и предлагали, все и выведется в алфавитном порядке.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 16:32
мановар, возможно я не глубоко понял ваше предложение, но в моем варианте есть только сортировка и один пробег по массиву со складыванием букв в пару заранее подготовленных мешков. Быстро, дешево, надежно и практично Но разумеется, даже такая простая задача может быть решена многими способами.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12844 / 7593 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
08.08.2017, 16:39
Цитата Сообщение от _Ivana Посмотреть сообщение
Быстро, дешево, надежно и практично
Только короче у меня как-то не получилось
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
#include <iostream>
#include <algorithm>
#include <cstring>
 
int main() {
    char strIn[256], * strOut;
    
    std::cout << "Symbols: ";
    std::cin.getline(strIn, 256);
    char * pointPos = strchr(strIn, '.');
    if ( ! pointPos ) {
        std::cerr << "Need a point at the tail!" << std::endl;
        return 1;
    }
    *pointPos = '\0';
    int len = pointPos - strIn;
    std::sort(strIn, pointPos);
    
    strOut = new char [ len + 1 ];
    strOut[len] = '\0';
    bool oddFound = false;
    char * pHead = strOut;
    char * pTail = strOut + len - 1;
    
    for ( int i = 0; i < len; i += 2 ) {
        if ( strIn[i] != strIn[i + 1] ) {
            if ( oddFound ) {
                std::cout << "NO" << std::endl;
                delete [] strOut;
                return 0;
            }
            else {
                strOut[len / 2] = strIn[i];
                oddFound = true;
                i -= 1;
            }
        }
        else {
            *pHead++ = strIn[i];
            *pTail-- = strIn[i];
        }
    }
    
    std::cout << "YES\n" << strOut << std::endl;
    
    delete [] strOut;
    return 0;
}
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 16:46
Цитата Сообщение от easybudda Посмотреть сообщение
Только короче у меня как-то не получилось
Ну если все делать по уму, с динамическим выделением по нью и удалением по делит, да еще транжирить строки... Такие олимпиадные задачи принято делать не по уму - нарезать сразу глобальный массивы результатов и писать все туда
1
1719 / 568 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
08.08.2017, 16:51
_Ivana, да те же яйца только в профиль. Допустим получили после сортировки
[AAAABBCCCCCDDDDDD] топаем вперед по нашему массиву : A - 4 шт. четн., делим на 2, по 2 шт. в наши мешки (или в один, а потом реверсом), с B - то же самое, C - 5 шт. нечет, запоминаем, устанавливаем флаг и т.д. Это для того что бы избежать
[CC] в мешки, [CC] в мешки, [CD] - не в мешки, надо возвращаться и колупаться по новой. Короче облегчить немного труд.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12844 / 7593 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
08.08.2017, 16:57

Не по теме:

Ну да, спортсмен из меня тот ещё...



мановар, так это их все пересчитывать прийдётся, по сути та же фигня, что с мапой или массивом счётчиков, только плюс к тому - отсортировали зачем-то. Тут же вся прелесть в том, что просто по две штуки берём, если одинаковые - рассовываем по краям, если нет - первую пихаем в середину, устанавливаем флаг и начиная со второй снова берём по две штуки...
1
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 17:02
Ну вот, приятно, что кто-то оценил прелесть подобных оптимизаций на спичках и ловлей блох Асимптотика то все равно О(n*log(n)) в любом случае - хоть с мапами, хоть по массиву несколько раз бегай...
0
354 / 135 / 28
Регистрация: 16.12.2012
Сообщений: 607
Записей в блоге: 1
08.08.2017, 17:19
Цитата Сообщение от _Ivana Посмотреть сообщение
Асимптотика то все равно О(n*log(n)) в любом случае
Линия будет

Добавлено через 15 секунд
Цитата Сообщение от _Ivana Посмотреть сообщение
Асимптотика то все равно О(n*log(n)) в любом случае
Линия будет
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 17:23
Я свою оценку взял из необходимости сортировки в моем варианте и поиска по ключам в мапе в других. Если без мапы искать по массиву, предполагая конечность алфавита, тогда О(n*m), где m-длина алфавита. Линии не вижу.
0
354 / 135 / 28
Регистрация: 16.12.2012
Сообщений: 607
Записей в блоге: 1
08.08.2017, 17:24
Тут вопрос трактовки. Если бы мощность алфавита была бы не известна - Вы правы.
А так прав я. Ибо по правила О большого - мы выбрасываем коэффициент.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 17:33
Ну в таком варианте трактовки я с натяжкой соглашусь Да и в условии
Цитата Сообщение от Fixer_84 Посмотреть сообщение
На вход программы подаются заглавные латинские буквы
- можно безо всяких мапов брать массив длиной 26 и считать по смещению.
0
1719 / 568 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
08.08.2017, 17:34
Понял что не догонял. При
[AAAABBCCCCCDDDDDD]
должны получить в [AABCCDDDCDDDCCBAA] , а не [AABDDDCCCCCDDDBAA] как думал.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
08.08.2017, 17:36
мановар, да, стоит задача получить лексикографически минимальный результат, а не слепить в центре те же буквы что и центральная, если их нечетное количество
0
1719 / 568 / 187
Регистрация: 12.03.2016
Сообщений: 2,169
08.08.2017, 17:43
_Ivana, за бурным обсуждением данная деталь и выскользнула из головы, бывает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.08.2017, 17:43

Добавить к слову наименьшее количество букв справа, чтобы получился палиндром
Здравствуйте! Решил несложную задачку на строки. Со временем выполнения все хорошо, но в нескольких тестах - неправильный ответ. Прошу...

Переставить буквы в строке так, чтобы первой буквой была гласная
Есть строка &quot;acomabugopabt&quot; Сколько есть различных способов переставить буквы в этой строке так, чтобы первой буквой была...

Определить, можно ли переставить буквы так, чтобы получился палиндром
3.На вход программы подаются прописные латинские буквы, ввод этих символов заканчивается точкой. Напишите эффективную по времени работы и...

Строка: Определить, можно ли переставить эти буквы так чтобы получился палиндром?
На вход программы подается прописные латинские буквы, ввод этих символов заканчивается точкой. Нужна программа определяющая можно ли...

Определить, можно ли переставить последовательность цифр так, чтобы получился палиндром
Задача 2. Палиндром. Написать программу, которая будет определять, можно ли переставить заданную последовательность цифр, так чтобы...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru