3 задачи по паскалю

msblast
Сообщения: 10
Зарегистрирован: 15 май 2007, 19:06

Решал свою контрольную по паскалю и залип на этих 3-х задачах, мыслей -0

№1
В городе N, 100 кондитерских магазинов. Известно что в каждом из магазинов не более 20 видов сластей в ассортименте. Какие виды сластей есть во всех магазинах. Существует ли магазин торгующий уникальной продукцией. Перечислите 5 видов сластей которые есть в большинстве магазинов города N. (ассортимент кондитерских магазинов рассматривается как длинна перечисляемого типа)
(я так понял тут нада записывать множества, точнее масиив множеств, только толком ни че не получается)

№2

Код: Выделить всё

Type
Tfigure=(circle,rectangle,triangle);
Tcolor=(red,green,blue);
Point=record
x,y:real
end;
figures=record
color:tcolor
case figure Type:tFigure of 
circle :( centre :p oint;radius:real);
rectangle :( s1,s2 :p oint);
triangle :( t1,t2,t3 :p oint)
end;
tlist=array[1..20] of figures;
var
list:tlist;
Определить:
1) Суммарную площадь всех фигур
2) Лежит хотябы один круг внутри прямоугольника
3) Количество треугольников голубого цвета
4) Каких фигур больше
(Тут надо дописать задачу)

№3
Текстовый фаил содержит сведения о наличии жаропонижающих лекарственных препаратов в аптеках города. Описание одного препарата от другого отделяется символом ; . Каждая строка файла содержит не более 80 символов. Если данного кол-ва символов не хватило, можно продолжить описание в следующих строках файла по указаному формату. Сведения состоят из номера аптекиб названия препаратаб его цены и названия страны изготовителя.
Структура строки файла:
Номер апетки,название препарата,Цена препарата,страна изготов.
Требуется найти:
1) Препарат с наименьшей ценой, на экран вывести название препарата, номер аптеки, страну изготов.
2) Найти аптеку с наиболее широким ассортиментом
(Здесь я так понял типизированный фаил, толькоя незнаю как работать с табуляцией)



Помогите пожалуйста
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

С магазинами - достаточно создать массив пар array of (array[1..2] of byte) of byte;
Каждый элемент массива - массив, в котором первый элемент - номер магазина, второй - номер сладости. Например
[[1,2],[1,3],[2,3]] - 1 магазин торгует сладостями №№2 и 3, 2 - только №3. Дальше все задачи решаются пробежками по этому массиву.

С аптеками - не обязательно типизированный, достаточно простого текстового. Считываешь строку, разбиваешь на слова (см. раздел "Алгоритмы"). Причем разбиение проводить так: сначала отрезать первое слово - это число с номером аптеки, потом отрезать по одному слову и склеивать их в одну строку до тех пор, пока очередное отрезанное слово не окажется числом. Тогда склеенная строка будет названием препарата (они иногда называются многословно, типа "Перекись водорода"), а последнее отрезанное слово - ценой. И тогда весь остаток строки будет страной-производителем. Записываешь это все в какую-то запись, запись кладешь в массив, а потом - все решается путем обхода массива в цикле.

ЗЫ: что-то я в последнее время все чаще встречаю подобные задачи. У меня впечатление, что институтские преподы очень любят делать на Паскале то, для чего вообще предназначены совсем другие продукты, типа MySQL
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
msblast
Сообщения: 10
Зарегистрирован: 15 май 2007, 19:06

Хыиуду,

С аптеками я почти разобрался...тут благодать сошла на меня

с магазинами: через массив массивов как то трудновато, еслиб массив множеств, со множествами легче делать операции (разность, обьеденение..)

А вот со второй задачей вообще низнаю что делать(
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

Насчет магазинов: здесь фактически два множества со связями "многие ко многим". Если бы каждое конкретное лекарство продавалось бы только в одном магазине, тогда работать со множествами имело бы смысл. Но здесь именно хранить данные удобнее в массиве.
А вот представлять их - можно и во множествах, даже более удобно. К примеру, найти множество всех лекарств, продающихся в магазине №5 (пусть массив массивов называется А, а множество - S)
for i:=1 to high(A) do
if A[1]= 5 then include(A[2],S)
Как-то так.

Со второй задачей - найди формулу определения площади треугольника по координатам вершин. Остальные площади находятся проще: круг - пи эр квадрат, прямоугольник - (s2.x-s1.x)*(s2.y-s1.y)

Круг находится в прямоугольнике, если centre.x-radius>=s1.x, centre.y-radius>=s1.y, centre.x+radius<=s2.x и centre.y+radius<=s2.y

Остальные два - пробегание по списку и суммирование: если круг - увеличиваем счетчик кругов, прямоугольник - прямоугольников, синий треугольник - синих треугольников
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Хыиуду писал(а):Со второй задачей - найди формулу определения площади треугольника по координатам вершин.
Есть формула Герона вычисления площади теругольника по трем его сторонам:

S = SQRT (p * (p-a) * (p-b) * (p-c))

где a, b, c - длины сторон треугольника,
а p - полупериметр треугольника: p = (a+b+c) / 2

А, зная координаты вершин, длины сторон определить несложно:
a = SQRT ( (t1.x - t2.x)^2 + (t1.y - t2.y)^2)
b = SQRT ( (t1.x - t3.x)^2 + (t1.y - t3.y)^2)
c = SQRT ( (t2.x - t3.x)^2 + (t2.y - t3.y)^2)
Остальные площади находятся проще: круг - пи эр квадрат, прямоугольник - (s2.x-s1.x)*(s2.y-s1.y)
Меня вот смутило, что у прямоугольника заданы лишь ДВЕ его вершины. Неужели авторы задачи считают, что этого достаточно, чтобы однозначно задать пямоугольник? Если, конечно, стороны должны быть параллельны осям координат, а указаныв две противоположные вершины (о чем, собственно, тоже не сказано), то да. А если условия параллельности осям нет, то прямоугольников множно нарисовать множество. Или фокус в том, что у них у всех будет одинаковая площадь?

UPD. Я подумал, и понял, что площади у прямоугольников будут разные, если они построены на двух противоположных вершинах. Действительно, если на данном отрезке, как на диаметра, провести окружность, то взяв любую точку на ней, мы получим прямоуголный треугольник с основанием - нашим диаметром. Т.е. половину прямоугольника. Но площадь треугольника (который - ровно половина прямоугольника) меняется (при одинаковом основании) в зависимости от его высоты. А высотами в данном случае будут перпендикуляры, опущенные из точки окружности на наш диаметр. Очевидно, что длины перпендикуляров будут различны. Следовательно, и площади прямоугольников - тоже различны.
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

согласен, условие поставлено некорректно. поэтому то, о чем умалчивается, мы просто толкуем так, как мы этого хотим :) можно потом в комментариях к проге описать.
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
msblast
Сообщения: 10
Зарегистрирован: 15 май 2007, 19:06

Вот с аптеками поговорил с училкой, выяснилось что фаил нада создавать в проге, и точка с зяпятой ненужны...начиркал :

Код: Выделить всё

program ex6;
uses crt;
type
aptek=record
number:integer;
name:string[10];
price:real;
made:string[10];
end;

var
F:file of aptek;
n:byte;
Fa:array[1..30] of aptek;

procedure add;
var
Fname:string[10];
i:byte;
c:char;
begin
assign(F,'Apteki.txt');
reset(F);
if IOresult=0 then
   Seek(F, FileSize(F))
else Rewrite(F);
i:=FileSize(F);
repeat
inc(i);
Writeln('Ввод данных о ',i,' аптеке :');
with Fa[i] do
     begin
     writeln('Введите номер аптеки');
     readln(number);
     writeln('Введите название препарата');
     readln(name);
     writeln('Введите цену препарата');
     readln(price);
     writeln('Введите страну изготовителя');
     readln(made);
     end;
write(F, Fa[i]);
writeln('Ввести данные об еще одной аптеке?');
readln(c);
until c in ['N','n','н','Н'];
close(F);
end;

procedure output;
var
Error:boolean;
Fname:string[10];
i:byte;
begin
Error:=true;
while Error do
begin
assign(F,'Apteki.txt');
reset(F);
Error:=(IOresult>0);
if Error then  writeln('Такой фаил несуществует');
end;
clrscr;
write(' ':6,'Номер.Апт.',' ':4);
write(' ':6,'Название',' ':4);
write(' ':6,'Цена',' ':4);
write(' ':6,'Изготовитель',' ':12);
for i:=1 to FileSize(F) do
    Begin
    writeln;
    Read(F, Fa[i]);
    with Fa[i] do
    begin
    write(' ',number:10);
    write(' ',name:23);
    write(' ',price:12:1);
    write(' ',made:17);
    end;
end;
close(F);
end;

procedure search;
var
Error:boolean;
Fname:string[10];
min:real;
i,pos:byte;
begin
Error:=true;
while Error do
      begin
      assign(F,'Apteki.txt');
      reset(F);
      Error:=(IOresult>0);
      if Error then  writeln('Такой фаил несуществует');
      end;
min:=100;               -----вот здесь косяк какой то, если сюда поставить                  min:=Fa[1].price (типа берет цену из первой записи) , то выводится какая то хренотень (
for i:=1 to FileSize(F) do
    begin
    Read(F, Fa[i]);
    with Fa[i] do
    if price<min then
       begin
       min:=price;
       pos:=i;
       end;
    end;
     writeln('Препарат с наименьшей ценой');
writeln;
write(' ':6,'Название',' ':4);
write(' ':6,'Номер.Апт.',' ':4);
write(' ':6,'Изготовитель',' ':4);
    with Fa[pos] do
    begin
    writeln;
    write(' ',name:13);
    write(' ',number:13);
    write(' ',made:22);
    end;
end;

begin
Writeln('1-Добавление записи');
Writeln('2-Просмотр файла');
Writeln('3-Поиск по файлу');
readln(n);
case n of
1: add;
2: output;
3: search;
end;
readln;
end.
А вот как теперь найти здесь аптеку с наиболее широким ассортиментом?
msblast
Сообщения: 10
Зарегистрирован: 15 май 2007, 19:06

Хыиуду писал(а): Со второй задачей - найди формулу определения площади треугольника по координатам вершин. Остальные площади находятся проще: круг - пи эр квадрат, прямоугольник - (s2.x-s1.x)*(s2.y-s1.y)

Круг находится в прямоугольнике, если centre.x-radius>=s1.x, centre.y-radius>=s1.y, centre.x+radius<=s2.x и centre.y+radius<=s2.y

Остальные два - пробегание по списку и суммирование: если круг - увеличиваем счетчик кругов, прямоугольник - прямоугольников, синий треугольник - синих треугольников
Это понятно, непонятно только как ввод данных осуществить, к примеру я делаю:

Код: Выделить всё

repeat
inc(i)
Writeln('Ввод данных о ',i,' фигуре :');
with list[i] do
writeln('Какая это фигура?');
readln(а вот куда записывать то?)
if (а вот куда это записывать) =circle then
    writeln('Введите ценр и радиус окружности');
    readln(куда это тоже записывать?)
и так далее (можно через case of)
а вот как запись в запись осущесвить?
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

msblast,
А если так:

Код: Выделить всё

var cChoice : char;
.............
writeln ('Укажите фигуру:');
writeln ('1. Круг');
writeln ('2. Прямоугольник');
writeln ('3. Треугольник');
writeln ('3. Треугольник');
writeln ('Сделайте Ваш выбор:');
readln (cChoice);
case (cChoice) of
  '1': list[i].Type = circle;
  '2': list[i].Type = rectangle;
  '3': list[i].Type = triangle;
  else
    writeln ('Ошибочный выбор');
end;
msblast
Сообщения: 10
Зарегистрирован: 15 май 2007, 19:06

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

тип фигуры записывается в List.Type
центр круга в list.centre.x и list.centre.y
радиус в list.radius
цвет в list.color

правильно?
Ответить