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

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

07.08.2017, 22:03. Показов 8115. Ответов 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
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
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
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
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
Ответ Создать тему
Новые блоги и статьи
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
Модель здравосохранения 17. Планы на выгорание
anaschu 23.05.2026
Вот конкретная схема реализации: В классе Работник добавить: накопленнаяУсталость — растёт каждый час работы, снижается в перерывы и болезни коэффициентПрезентеизма — снижает продуктивность. . .
Изменение цветов в палитре gif файла aka фавикона
russiannick 23.05.2026
Изменение цветов в палитре gif файла, юзаемого как фавиконка в составе html-файла, помещенная в base64, средствами нативного Java Script, навеянное сном в майский день. Для работы необходим браузер,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru