• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

    Если вы у нас впервые, загляните на страницу о форуме и правила – там коротко описано, как задать вопрос так, чтобы быстро получить ответ. Чтобы создавать темы и писать сообщения, сначала зарегистрируйтесь, а затем войдите под своим логином.

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

Пара задач с олимпиады

  • Автор темы Автор темы ummasha
  • Дата начала Дата начала
везёт) а мне самому приходилось разбираться с кодами:(
 
Вот ссылка на сайт, где очень много полезной информации для тех, кто создает сайты:
http://htmlbook.ru/
 
У меня возникло несколько вопросов по следующей задаче: подсчитать сумму произведений последовательных пар элементов в целочисленном массиве из 30 элементов:

Program P1_93;
const n=30;
Var a:array[1..n] of integer;
Sum_P,i:integer;
BEGIN
For i:=1 to n do
readln(a);
Sum_P:=0;
For i:=1 to n div 2 do
begin
Sum_P:=Sum_P+a[2*i]*a[2*i-1];
end;
writeln('Sum_P=',Sum_P);
END.

Такое решение было предложено в задачнике. Для чего нужно вот это?
И почему они написали так? Если это условие изменить, то Паскаль пишет:выход за границы диапазона изменения индекса 1..30.
 
У меня возникло несколько вопросов по следующей задаче: подсчитать сумму произведений последовательных пар элементов в целочисленном массиве из 30 элементов:

Program P1_93;
const n=30;
Var a:array[1..n] of integer;
Sum_P,i:integer;
BEGIN
For i:=1 to n do
readln(a);
Sum_P:=0;
For i:=1 to n div 2 do
begin
Sum_P:=Sum_P+a[2*i]*a[2*i-1];
end;
writeln('Sum_P=',Sum_P);
END.

Такое решение было предложено в задачнике. Для чего нужно вот это?
И почему они написали так? Если это условие изменить, то Паскаль пишет:выход за границы диапазона изменения индекса 1..30.


Маша, а Вы попробуйте мысленно начать подставлять значения i = 1, 2, 3, и т.д. до 15.
И сразу увидите, что такой цикл разбивает массив на пАры, (2, 1), (4, 3) и т.д., перемножает числа в пАрах и полученные произведения складывает, что и требуется по условию задачи. Вы не написали, как меняли условие, подозреваю, что просто пытались убрать целочисленное деление, но тогда уже при i = 16 программа попытается перемножить a[32] и a[31], что недопустимо.
 
Попробую это осознать и запомнить))) Может, когда-нибудь пригодится :)
 
Попробую это осознать и запомнить))) Может, когда-нибудь пригодится :)

Тогда еще пара замечаний. Рассмотрим фрагмент:

...
Sum_P:=0;
For i:=1 to n div 2 do
begin
Sum_P:=Sum_P+a[2*i]*a[2*i-1];
end;
...

1. Вот что там действительно лишнее, так это операторные скобки begin и end, поскольку тело цикла состоит всего из одного оператора.

2. Конечно, можно и без целочисленного деления. Скажем, так:

Sum_P:=0;
i:=0;
REPEAT
i:=i+2;
Sum_P:=Sum_P+a*a[i-1];
UNTIL i=n;

Но вариант из книжки красивее.
 
Сегодня на курсах по информатике мы решили следующую задачу:
picture.php

Решение:

Program C_4;
Var a:array[1..99] of integer;
c:char;
st,n,i,min:integer;
BEGIN
For i:=1 to 99 do
a:=0;
readln(n);
For i:=1 to n do
begin
Repeat
read(c)
Until c=' ';
Repeat
read(c)
Until c=' ';
readln(st);
a[st]:=a[st]+1;
end;
min:=n;
For i:=1 to 99 do
If (a>0)and(a<min) then
min:=a;
For i:=1 to 99 do
If a=min then
writeln(i);
END.

Ход решения преподаватель нам объяснил, но мне интересно, работает ли эта программа. Когда я стала вводить что-то вроде:Иванов ИИ 60, она выдала ошибку ввода в 8-й строке(((
 
Естественно. Начинать надо с ввода количества учеников (n), потом нажать Enter, а уж потом вводить построчно список.
Да, а после ввода инициала надо ставить точку.
 
Vladimir_S, сделала так, как вы сказали, и все получилось :) Спасибо :)
 
Vladimir_S, сделала так, как вы сказали, и все получилось :) Спасибо :)

Маша, это, конечно, прекрасно, только вот... Всё же рискну дать один совет - попробуйте научиться ЧИТАТЬ программы. Так, строчку за строчкой, осмысливая что там и зачем. Поверьте, это действительно нужно. Вам.
 
Когда я смотрю на программу, у меня всегда возникают какие-то вопросы. Я честно пытаюсь разобраться, и иногда у меня получается, но не всегда. Поэтому я задаю вопросы на форуме и благодарна вам за все объяснения.
 
Когда я смотрю на программу, у меня всегда возникают какие-то вопросы. Я честно пытаюсь разобраться, и иногда у меня получается, но не всегда. Поэтому я задаю вопросы на форуме и благодарна вам за все объяснения.

Главное, не стесняйтесь. Задавайте вопросы, переспрашивайте, если чего недопоняли. Всегда поможем. Успехов!
 
Сегодня я разбирала задачи типа С из одного сборника, сравнивала свои решения с книжными и проверяла программы на компе. Я решила следующую задачу: найти строку с наименьшей суммой элементов в целочисленном массиве 10 на 20, напечатать номер строки и сумму ее элементов.

Program c2_3;
Const n=4;m=5;
Var a:array[1..n,1..m] of integer;
i,j,S,Sm,Nm:integer;
BEGIN
For i:=1 to n do
begin
For j:=1 to m do
readln(a[i,j]);
end;
Nm:=1;
For i:=1 to n do
Sm:=Sm+a[i,j];

For i:=1 to n do
begin
S:=0;
For j:=1 to m do
begin
S:=S+a[i,j];
end;
If S<Sm then
begin
Nm:=i;
Sm:=S;
end;
end;
writeln('Sm=',Sm,'Nm=',Nm);
END.

Это - мое решение, а в книге вместо этого было просто Sm:=0. Но тогда задача решалась неверно. Я подумала, что за минимальную сумму элементов строки массива надо принять не ноль, а сумму элементов первой строки. Это правильное решение?
 
Это - мое решение, а в книге вместо этого было просто Sm:=0. Но тогда задача решалась неверно. Я подумала, что за минимальную сумму элементов строки массива надо принять не ноль, а сумму элементов первой строки. Это правильное решение?

Увы, нет. Давайте разберем задачу внимательно и неторопясь.

Program c2_3;
Const n=4;m=5;

Так, здесь Вы уменьшили размер массива. Не принципиально. Можно.

Var a:array[1..n,1..m] of integer;
i,j,S,Sm,Nm:integer;
BEGIN
For i:=1 to n do
begin
For j:=1 to m do
readln(a[i,j]);
end;

Ввели значения элементов массива. Пока всё правильно.

Nm:=1;
For i:=1 to n do
Sm:=Sm+a[i,j];


Не пойдет по ряду причин:
1. Не введено исходное значение Sm. Можно, конечно, понадеяться на то, что в Вашей реализации Паскаля всем переменным исходно присваивается значение "0", но лучше не надо. Это не всегда так.
2. Значение переменной j (номер столбца) будет унаследовано от предыдущего цикла, т.е. "5". Это так и задумано?
Между прочим, в книжке написана полная ерунда: Sm:=0 это неправильно! А как надо? А вот как.
Идея алгоритма состоит в том, что последовательно вычисляются суммы каждой из строк, и если следующая сумма оказывается МЕНЬШЕ предыдущей, то она ВРЕМЕННО и принимается за искомую, и номер этой строки тоже ВРЕМЕННО принимается за искомый. Если же значение суммы элементов строки ПРЕВЫСИТ значение суммы элементов предыдущей строки, то значение Sm и искомого номера НЕ ИЗМЕНЯТСЯ. А поэтому в качестве исходного значения суммы следует взять НАИБОЛЬШЕЕ ВОЗМОЖНОЕ, т.е. Sm:=32000;


For i:=1 to n do
begin
S:=0;

For j:=1 to m do
begin
S:=S+a[i,j];
end;

Здесь ошибки нет, но begin и end можно спокойно убрать, поскольку тело цикла содержит только один оператор.

If S<Sm then
begin
Nm:=i;
Sm:=S;
end;
end;
writeln('Sm=',Sm,'Nm=',Nm);
END.

Вроде всё правильно.

Таким образом, окончательно:

Program c2_3;
Const n=4;m=5;
Var a:array[1..n,1..m] of integer;
i,j,S,Sm,Nm:integer;
BEGIN
For i:=1 to n do
begin
For j:=1 to m do
readln(a[i,j]);
end;
Nm:=1;
Sm:=32000;
For i:=1 to n do
begin
S:=0;
For j:=1 to m do
S:=S+a[i,j];
If S<Sm then
begin
Nm:=i;
Sm:=S;
end;
end;
writeln('Sm=',Sm,'Nm=',Nm);
END.


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

1. Вместо строки Sm:=32000 следует вставить:
Sm:=0;
Nm:=1;
for j:=1 to m do
Sm:=Sm+a[Nm,j];
2. Последующий цикл можно начать c i=2, т.е
For i:=2 to n do
 
Последнее редактирование:
Какое замечательное решение! А я до такого не додумалась((( Еще вопрос: если нужно будет найти максимальную сумму элементов, то Smах:=-32000?
 
Какое замечательное решение! А я до такого не додумалась((( Еще вопрос: если нужно будет найти максимальную сумму элементов, то Smах:=-32000?

Разумеется. А вообще это стандартный програмистский прием.
Обратите внимание - я там добавил вариант. Тоже можно. Но длиннее получается.
 
Vladimir_S, вы как всегда мне помогли :) Решения мне понятны, надеюсь, что смогу сама решать такие задачи.
 
У меня возник такой вопрос: что можно считать уникальными элементами массива, а что - различными? На курсах преподаватель для примера записал массив: 1123322 и сказал, что там есть три уникальных элемента: 1,2,3. Но я думала, что это различные элементы, а уникальные - это те, которые встречаются в массиве только один раз...
 
У меня возник такой вопрос: что можно считать уникальными элементами массива, а что - различными? На курсах преподаватель для примера записал массив: 1123322 и сказал, что там есть три уникальных элемента: 1,2,3. Но я думала, что это различные элементы, а уникальные - это те, которые встречаются в массиве только один раз...

Тут, Маша, я, к сожалению, помочь не могу. Вообще-то в части программирования я самоучка, поэтому некоторых терминологических тонкостей не знаю. Порылся в Сети - обозначение "уникальные элементы массива" встретил на нескольких форумах у сишников, и, как понял, вроде это именно как трактует Ваш преподаватель, т.е. 1,2, и 3. Но хорошо бы кто-нибудь уточнил.
 
Назад
Сверху