Задача
Один из способов мошенничества, разработанных О. Бендером, заключался в следующем. Он вырезал полоску бумаги, содержащую несколько цифр из суммы чека (можно вырезать и крайние цифры), разрезал ее на две части, переставлял эти две части местами и аккуратно подклеивал обратно. Напишите программу, определяющую максимальное число, которое может быть получено в результате указанной манипуляции.
Входные данные
Во входном файле в первой строке содержится одно целое положительное число не более чем из $100$ цифр.
Выходные данные
В выходной файл вывести одно число – максимальное число, которое можно получить в результате указанной манипуляции, или исходное число, если увеличить число невозможно.
Тесты
Входные данные | Выходные данные |
$123321$ | $332121$ |
$7888778888878888788878878777887$ | $8888878888788878887778878777887$ |
$1091$ | $9100$ |
$26364$ | $64263$ |
$98765$ | $98765$ |
Код программы
String
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 |
#include <iostream> using namespace std; int main() { string s; cin >> s; string maxS = s; int start = s.size() - 1; bool found = false; for(int i = 0; i < s.size() and !found; i++){ for(int j = i; j < s.size() and !found; j++){ if(s[j] > s[i]){ start = i; found = true; } } } for(int j = start + 1; j < s.size(); j++){ if(s[j] >= s[start]) { string curMax = s; for (int k = j; k < s.size(); k++) { curMax.insert(start + k - j, 1, s[k]); curMax.erase(k + 1, 1); maxS = max(curMax, maxS); } } } cout << maxS; return 0; } |
C-String
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 |
#include <iostream> #include <cstring> using namespace std; const int MAX_LENGTH = 101; int main() { char s[MAX_LENGTH]; cin >> s; char maxS[MAX_LENGTH]; strcpy(maxS, s); int size = strlen(s); int start = size - 1; bool found = false; for(int i = 0; i < size and !found; i++){ for(int j = i; j < size and !found; j++){ if(s[j] > s[i]){ start = i; found = true; } } } for(int j = start + 1; j < size; j++){ if(s[j] >= s[start]) { char curMax[MAX_LENGTH]; strcpy(curMax, s); for (int k = j; k < size; k++) { char temp = s[k]; for(int i = k; i > start + k - j; i--){ curMax[i] = curMax[i - 1]; } curMax[start + k - j] = temp; if(strncmp(curMax, maxS, size) > 0){ strcpy(maxS, curMax); } } } } cout << maxS; return 0; } |
Решение задачи
Пусть заданы два числа: $a = \overline{a_1a_2 \ldots a_k},\ b = \overline{b_1b_2 \ldots b_k}$. Тогда $a > b \Leftrightarrow \exists i: \ \forall j < i \ a_j = b_j \ \wedge \ a_i = b_i$. Отсюда получаем необходимое условие получения максимального числа при перестановке в записи числа $a$ групп цифр $\overline{a_ia_{i+1} \ldots a_l}$ и $\overline{a_ja_{j+1} \ldots a_m} \ l<j$ местами: $i = \min_{1 < s < k} s: \ \exists t>s: \ a_t \gt a_s$. Если такое $i$ существует, то далее мы делаем перебор по всем возможным перестановкам, таким что первая группа чисел начинается с индекса $i$ и таким образом находим максимально возможное число. В противном случае данное число уже является максимальным.
Ссылки
Условие задачи на e-olymp
Решение на e-olymp. String
Решение на e-olymp. C-String
Код решения на Ideone. String
Код решения на Ideone. C-String
Решение для С-строк можно писать здесь же.
Добавьте, пожалуйста, метки (ключевые слова) и укажите все категории.
Игорь Евгеньевич, исправил