Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337

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

07.08.2017, 22:03. Показов 8209. Ответов 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru