![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() |
Unconnected |
![]()
Сообщение
#1
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Привет всем.
Меня заинтересовала задача из соседней темы, про перестановки в числах. Цитата Задача 4 "Сумма двух чисел" Имя входного файла: sum.in Имя выходного файла: sum.out Максимальное время работы на одном тесте: 2 секунды Максимальный объем используемой памяти: 64 мегабайта Заданы три числа: a, b, c. Необходимо выяснить, можно ли так переставить цифры в числах a и b, чтобы в сумме получилось c. Формат входных данных Входной файл содержит три целых числа: a, b, c (0 < a, b, c < 109). Числа разделены пробелом. Формат выходных данных Если искомая перестановка цифр возможна, необходимо вывести в выходной файл слово YES, в противном случае — выведите слово NO. При положительном ответе необходимо вывести во второй строке выходного файла число x, получаемое перестановкой цифр числа a, и число y, получаемое перестановкой цифр числа b, сумма которых равна c. Числа x и y не должны содержать ведущих нулей. Числа в строке разделены пробелом. Примеры входных и выходных файлов sum.in sum.out 12 31 25 ***YES*** **********12 13*** 12 31 26 ***NO*** Вот что я сделал: const m=6; Мой алгоритм перестановок (для трёхзначных чисел) основан на том, что если в числе переносить первую цифру в конец, пока не получится исходное число, а потом поменять 2 и 3 цифры местами и сделать то же самое, то получатся все перестановки.. Например: 123 231 312 меняем, 132 321 213 Получилось 6 перестановок, как раз 3!, как и должно быть. Моя программа почему-то не заполняет корректно массив (процедура Generate). Сообщение отредактировано: Unconnected - 18.01.2010 13:21 -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
![]() ![]() |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Цитата Моя программа почему-то не заполняет корректно массив (процедура Generate) Потому что она у тебя вылетает за пределы этого массива: открытый массив индексируется с 0, а не с того индекса, который задан при описании типа. Соответственно, не до M, а до (M-1)... Включи контроль границ и убедись... |
Unconnected |
![]()
Сообщение
#3
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Получается, надо константу m сделать равной 7? Всё равно не заполняет..
-------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
![]()
Сообщение
#4
|
Гость ![]() |
Цитата Всё равно не заполняет.. Во-первых, я не совсем понял вот этот твой финт:Цитата if (length(v)<3) then repeat v:=v+'0' until (length(v)=3); 1) type 2) procedure generate(VAR m:arrst;v:st);и третье - скорее всего, главное, заполнял бы массив вот таким образом: i:=1;, понимаешь разницу между тем, что сделал я, и тем, что делал ты? В моем случае длина строки устанавливается корректно, в твоем - нет. |
Unconnected |
![]()
Сообщение
#5
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Короче, я решил... вроде бы... Добавил кое-что, код, конечно, не очень красивый, зато работает.
const m=6; Кстати, volvo, я так и не понял, почему твой код заполнения массива работает, а мой - нет? Мой ведь вроде бы на те же позиции копирует символы, только вручную, а твой просто присоединяет, вроде как и на те же места.. -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
![]()
Сообщение
#6
|
Гость ![]() |
Цитата а твой просто присоединяет, вроде как и на те же места.. Мало просто скопировать символы... Надо еще и длину строки установить, если ты заполняешь строку вручную. А если делать так, как я показал - то это делает компилятор, тебе об этом можно не заботиться... |
Unconnected |
![]()
Сообщение
#7
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
А как установить её, длину, вручную? Может, SetLength?
-------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
![]()
Сообщение
#8
|
Гость ![]() |
Цитата Может, SetLength? Если у тебя 32-битный компилятор - то SetLength, если 16-битный - то прямой записью длины строки в ее нулевой байт... |
Unconnected |
![]()
Сообщение
#9
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Ого, не знал, спасибо за помощь
![]() -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
Lapp |
![]()
Сообщение
#10
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Обычно в подобных случаях генерировать перестановки проще всего с помощью рекурсии. Вот, смотри:
const Эта программа работает с числами любой длины и любым количеством слагаемых (но последнее нужно задавать заранее константой m). Конечно, время работы несколько страдает.. Но при m=2, пролетает быстро; не исключено, что в 2 сек уложишься. Разберешься? Комменты по запросу ![]() -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Lapp |
![]()
Сообщение
#11
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Unconnected, можно я выскажу несколько замечаний?
Во-первых, при входных данных: 53 10 135 - твоя программа выдает: YES 35 10 135 - что неверно.. Далее, у тебя путаница в передачей массива в подпрограмму. Нужно сделать специальный тип и передавать его. Конструкция, которую использовал ты (array без пределов) в данном случае не годится, она служит другой цели и используется иначе. Я сделал изменения в твоем коде (помечено //), посмотри; так программа не вылетает при включенном range check. Отступы.. Они должны быть ВСЕГДА на одну и ту же величину. Сдвиг НЕ ДОЛЖЕН зависеть от того, за чем он идет: var, type или begin в конце строки - всегда на одно и то же число позиций (обычно 2, но можно и 4) от начала предыдущей строки. Исключений нет. Точка. Это было непререкаемое правило. А теперь совет.. Лучше писать begin (repeat, case..) не на новой строке, а на той же. Это не только позволяет сэкономить строчку и отступ, но - самое главное - позволяет практически исключить такую ситуацию: for i:=1 to 5 do Лучше так: for i:=1 to 5 do begin Если пишешь так, то появление в коде сдвинутой влево строки, НЕ начинающеся с end - почти всегда признак ошибки. Блок всегда начинается со строки, заканчивающейся begin (repeat, case..) и заканчивается строкой, начинающейся с end (until), и его тело сдвинуто. Всякое отступление от этого правила - признак возможной ошибки. Исключения случаются (они вносятся обычно оператором if .. then .. else), но их тоже проще отловить, если точно следуешь этому правилу. Очень рекомендую привыкнуть к такому способу написания кода. Теперь твоя программа, немного исправленная мной. const Надеюсь, ты сможешь извлечь из этого пользу )). И жду исправления работы в описанной выше ситуации! ![]() -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
![]()
Сообщение
#12
|
Гость ![]() |
Цитата Далее, у тебя путаница в передачей массива в подпрограмму. Нужно сделать специальный тип и передавать его. Конструкция, которую использовал ты (array без пределов) в данном случае не годится, она служит другой цели и используется иначе. А я уже говорил, что надо бы описывать тип (в сообщении №4 я назвал его arrst), но автор продолжает упорно использовать открытые массивы, из-за чего и огребает проблемы на ровном месте... Посмотрим, получится ли у тебя его убедить... |
Unconnected |
![]()
Сообщение
#13
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Короче, переделал я вообще механизм программы, т.к. добавление нулей это, видимо, дохлый номер, из-за которого и получалась ошибка, приведённая Lapp'ом.
Про передачу в программу массива без пределов - просто я считал, что так и нужно передавать массивы в качестве входных параметров процедур\функций. Буду знать) Lapp, за форматирование спасибо, приму к сведению (уже даже вроде бы принял, правя код) ![]() С рекурсивным решением разберусь, мне как раз надо научиться делать такое. -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
![]()
Сообщение
#14
|
Гость ![]() |
Цитата Procedure generate(m:tArSt;v:tst;num:byte); |
Unconnected |
![]()
Сообщение
#15
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Мм нет вроде, а что, что-то забыл?
![]() -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
![]()
Сообщение
#16
|
Гость ![]() |
Там не хватает слова Var... Не надо передавать в процедуру массив только как хранилище данных, заполнять его там, и тут же копировать в глобальную переменную. Ибо сразу возникает вопрос: а зачем ты вообще массив передаешь в процедуру?
Я в курсе, что ЗДЕСЬ (в данной программе) это работает... Но у тебя в процедуру передается лишний параметр, от которого можно избавиться (я про num). К тому же внутри процедуры моментально уберется лишний же цикл и условие... И вообще, это - неправильный путь. Правильный - работать с подпрограммами через параметры, а не через побочные эффекты... И опять я убеждаюсь, что все, что делается мной на форуме пропускается мимо ушей... Я ж писал, "Как не надо писать программы", и там говорилось в частности о том, что надо избегать использования глобальных переменных, и о том, что переменная должна описываться как можно ниже в тексте программы - нет, опять этого никто не читает... Неинтересно? Заработало и ладно? Ну, что ж... Больше в этот процесс вмешиваться не буду, пишите, "чтоб работало, сдам и фиг с ним". |
Unconnected |
![]()
Сообщение
#17
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Да, и правда, если добавить var, то переписывание в глобальный массив становится ненужным... Только num всё равно передавать придётся, ибо с помощью него записывается длина v в массив длин.
volvo, у меня не такой опыт в программировании, чтобы сразу делать так, как правильнее, а не как в голову пришло. -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
Lapp |
![]()
Сообщение
#18
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
А я уже говорил, что надо бы описывать тип Извиняюсь, повторился. Но в данном случае каша маслом не испортилась, пациент все же скорее жив, чем мертв, в отличие от многих других )). Вдвоем убедим! ... Посмотрим, получится ли у тебя его убедить... ![]() добавление нулей это, видимо, дохлый номер, из-за которого и получалась ошибка Да, то, что лидирующие нули не нужно учитывать, довольно сильно меняет ситуацию. Я рыпнулся было делать перестановки, но быстро остыл и переключился на рекурсию. Не хочу сказать, что это невозможно или намного труднее, но все же требует внимательности в разработке алгоритма. А рекурсия - дубовый метод, много мозгов не требует )). Тут, правда, осложнение в том, что переставляемая строка разбита на участки (числа); это потребовало передачи двух параметров в рекурсивную процедуру. А тем более, начальные условия такие щадящие. [прошло полчаса] Ха, интересно! Я думал, что увеличение количества чисел резко замедлит работу программы. Но..Например, вот такие входные данные: 1372 62 552 381 6924 91 1583 4973 21 8119 30504 (при m=10, разумеется) легко выдают ответ: YES - и увеличения времени на глаз не заметно! А штука в том, что.. Unconnected, сможешь ответить, почему? ![]() -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
![]()
Сообщение
#19
|
Гость ![]() |
Цитата Только num всё равно передавать придётся Это тебе только кажется ![]() Цитата ибо с помощью него записывается длина v в массив длин. Это значит что? Ты просто "не умеешь это готовить". Вот твоя же программа, но туда кое-что добавлено, я комментариями оставил твой прежний вариант. И что, понадобилось передавать num?const |
Lapp |
![]()
Сообщение
#20
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
volvo, я понимаю твое возмущение:
пишите, "чтоб работало, сдам и фиг с ним". - и я тебя поддерживаю, но Unconnected'а на этот раз это, вроде, не должно касаться, ибо эту задачу он стал делать, вроде как по собственной инициативе из чистого интереса )). На все требуется время, даже на запоминание азбучных истин ![]() -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
![]() ![]() |
![]() |
Текстовая версия | 21.07.2025 10:59 |