Помощь - Поиск - Пользователи - Календарь
Полная версия: Помогите с олимпиадной задачкой!
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Berta
...недавно прошёл школьный этап олимпиады по информатике. это одна из задач, которую я не смогла решить. помогите, пожалуйста, с решением и если можно объясните как решать...

Цитата
Во входном файле записана последовательность чисел в странном формате:
у каждого числа сначала записано количество цифр в этом числе, а потом через
пробел - сами цифры. Последовательность заканчивается числом 0.

В выходной файл нужно вывести сначала количество чисел в последовательности,
а потом - сами числа.

Количество чисел в последовательности не превышает 1000. В числах - не более
4-х знаков.

Примеры:
Пример 1
input.txt output.txt
2 2 7 3 3 5 1 0 2 27 351


...заранее спасибо!
Krjuger
С решением поможем, вы только продемонстрируйте свои попытки, чтобы было от чего отталкиваться.
Berta
Цитата(Krjuger @ 15.10.2012 20:40) *

С решением поможем, вы только продемонстрируйте свои попытки, чтобы было от чего отталкиваться.


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

 var a:array [1..1000] of integer;
c,i,x:integer;

begin

assign(input,'input.txt');
reset(input);
assign(output,'output.txt');
rewrite(output);

read(x);

for i:=1 to x do begin
read(a[i]);
end;

c:=0;

for i:=1 to x do begin
c:=c*10+x;

end;

write©;
end.


...может просто подскажете что сюда добавить ещё нужно и в каком порядке, а я попытаюсь написать...
Krjuger
Мда логика действительно не верная,но у меня есть вопрос,который не обговорен в задании, В задании говориться,что 0 это конец последовательности чисел, но возникает вопрос допустим ли 0 в самой записи числа например.
2 3 4 3 3 0 3 0 на входе и на выходе 2 34 303 или должно выйти сообщение об ошибке?
Berta
на самом деле там про это вообще ничего не говорится. может быть, можно создать условие, что если ноль последнее число, то удалить. только плохо ссебе представляю как это условие написать.
Krjuger
Нет, вы не поняли мой вопрос. Ноль обязательно должен быть последним числом, иначе ошибка, а вот вопрос что делать с нулем,если он где-нибудь в середине файла. Мне без разницы,это вопрос пары строчек,но сказать, как вам нужно должны вы,а не я придумывать. Как только этот вопрос будет решен, приступим к самому алгоритму и коду. smile.gif
Berta
Цитата(Krjuger @ 16.10.2012 20:48) *

Нет, вы не поняли мой вопрос. Ноль обязательно должен быть последним числом, иначе ошибка, а вот вопрос что делать с нулем,если он где-нибудь в середине файла. Мне без разницы,это вопрос пары строчек,но сказать, как вам нужно должны вы,а не я придумывать. Как только этот вопрос будет решен, приступим к самому алгоритму и коду. smile.gif


...раз в задаче не сказано, то не нужно мне. так что давайте перейдём к алгоритму... smile.gif
Федосеев Павел
Sorry, если нарушил воспитательный процесс:
var
a: array [1..1000] of Integer;
Count,
Number,
Digit,
NumLen,
i: Integer;
begin
Assign(input, 'input.txt');
Reset(input);
Count:=0;
repeat
Read(input, NumLen);
if NumLen=0 then
Break;
Number:=0;
for i:=1 to NumLen do
begin
Read(input, Digit);
Number:=Number*10+Digit;
end;
Inc(Count);
a[Count]:=Number;
until FALSE;
Close(input);

Assign(output, 'output.txt');
Rewrite(output);
Write(output, Count);
for i:=1 to Count do
Write(output, ' ', a[i]);
Close(output);
end.
Berta
Павел, извиняться не нужно...процесс, конечно, вы нарушили, но в вашей программе я всё равно мало что поняла, к сожалению...unsure.gif мне бы объяснить это всё поэтапно...
Федосеев Павел
Этап чтения и формирования массива чисел для дальнейшего вывода.
1. Организуем бесконечный цикл чтения
repeat
.......
until FALSE;

2. Согласно формату входных данных считываем количество цифр в будущем числе
    Read(input, NumLen);

3. Проверяем условие завершения входной последовательности, т.е. роверяем введённое число на 0
    if NumLen=0 then
Break;

4. Теперь, понимая, что нужно принять ещё одно число, начинаем его считывать из входного файла по одной цифре, и формировать из цифр число
    Number:=0;
for i:=1 to NumLen do
begin
Read(input, Digit);
Number:=Number*10+Digit;
end;

5. Теперь у нас есть число Number и мы для дальнейшего использования (вывода в файл) сохраняем его в массиве, а заодно подсчитываем количество введённых чисел (Count)
    Inc(Count);
a[Count]:=Number;

6. Переход к п.2.

Этап вывода результатов в файл.
1. Выводим в файл количество введённых чисел
  Write(output, Count);

2. Организуем цикл от 1 до количества введённых чисел (Count) и выводим числа в файл
  for i:=1 to Count do
Write(output, ' ', a[i]);


Всё.
Krjuger
Федосеев Павел, извини,что врываюсь,но есть пара моментов.
На подобной входной цепочке
2 3 4 6 5 3 4 5 3 5 6 7 7 5 3 7 5 4 6 7 8 9 6 4 3 3 6 7 4 3 6 7 8 5 4
Мне выдало следующий результат.
7 34 10247 -11057 6789 -25078 678 -25536
Согласись, что он не соответствует действительности.
И еще, твоя программа одинаково работает,что с нулем в конце,что без нуля, я думаю,что не зря в условии говорилось про ноль в конеце последовательности, поэтому, если чтение файла заканчивается не нулем,то нужно выдать какую нибудь ошибку.Хотя согласен, что в условии это не бговорено,поэтому на усмотрении программиста, просто я вообще тогда не понимаю смысла этого нуля....
Федосеев Павел
1. Неправильные результаты.
Напомню условие задания из первого поста:
"Количество чисел в последовательности не превышает 1000. В числах - не более 4-х знаков".

Отсюда и моё решение о длине массива a, и тип элементов массива integer.

Вообще-то, по-началу хотел использовать String[4], но мысль о незначительном усложнении ввода (на Паскале, естественно, а не в кодах) и последующие пояснения новичку привела к решению использовать тип integer.

2. Нуль, как последний символ.

Мой грех. Не протестировал без него. Наверное стоит добавить проверку на ошибки чтения файла, но оставлю это на усмотрение топикстартера.
Как уже неоднократно говорилось: "на форумах всё равно дают плохие советы". Сейчас не могу найти ссылку на развёрнутое пояснение этой мысли от Gunsmoker'а.
Krjuger
Да, согласен, мой косяк,но вопрос с нулем все еще в силе. Кстати нужно еще один момент продумать, может лучше сделать цикл не бесконечным? Потому что чисто гипотетически я туда могу ввести более тысячи чисел....
until (FALSE or Count>=1000);
Принципи у Count нет возможности перескочить 1000 поэтому можно использовать.
until (FALSE or Count=1000);
Федосеев Павел
Пусть ТС решает и реализует необходимый функционал. Он просил лишь алгоритм основной задачи.
Berta
Павел, что за функция break?и как я поняла, Вы работаете в ABC, а я в TP7, поэтому меня ещё в ступор всё это вводит, хотя в принципе перевести не проблема...
Федосеев Павел
А моя версия компилируется в TP7?

Если компилируется, то Break присутствует в нём. А это в свою очередь говорит о наличии контекстной справки, а если скопировать нужный "turbo.tph" то и на русском языке.

Контекстная справка вызывается так: ставим курсор на интересующее слово и нажимаем Ctrl-F1.

Кроме того, есть множество справочников по TP7. О них можно уточнить у Google.

P.S. На правах рекламы. У меня не ABC, а FreePascal (FPC). В режиме совместимости - полная копия TP7. При соответствующих настройках, его можно "прикрутить" к красивым редакторам в Windows типа SciTE (здесь на форуме очень хорошие материалы об этом). Это не считая наличия Delphi-подобного RAD - Lazarus.
Krjuger
А еще языки программирования высокого уровня хороши тем, что там весьма неплохо используется смысл самих слов( если конешно программисты не леняться и не называют все буквами или абривиарурами) В данном случае, Break делает как раз то, что он и означает на английском языке, а именно прерывает выполнение цикла. А Exit, например, осуществляет выход из программы.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.