Помощь - Поиск - Пользователи - Календарь
Полная версия: запутался в задачах чютчють одна норм а другая с ошибкой одной
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
maksimla
я сечас прохожу все что связано с двоичным массивом.
7 задачка две дороги и стоят 4 светофора по два на каждой дороги.
для пешеходов загорается зеленый свет в то самое время как на кнопку нажал и горит 30 секунд. Данные записываются в центре когда именно нажал пешеход на кнопку.
напишите а) идею решения
б) программу сколько секунд за сутки горит зеленый свет на всех светофорах.
Первичные данные записаны в файле duom.txt. На первой строчке записано натуральное число n (1 ≤ n ≤ 1000) . В последующих n строчках записано такие данные D или K D - правая K - левая сторона пути, потом записаны 3 неотрицательные числа val - часы, min - минуту и sek - секунды, показывающие когда нажал пешеход на кнопку, (0 ≤ val ≤ 23, 0 ≤ min ≤ 59, 0 ≤ sek ≤ 59).
Результат записывается в секундах в файл rez.txt.
пример
первичные данные
8
K 21 1 59
D 7 8 0
K 13 55 13
D 13 54 59
D 21 2 29
K 7 8 0
D 7 7 50
K 13 55 30
результат
44
обьяснение
7 8 0 загорелся свет в обоих частях и горел 30 секунд
D 13 54 59 в правой загорелся
K 13 55 13 в левой загорелся и горел в месте 14 секунд. Общее горения 44 секунды.

непонял почему они еще непощетали это
K 7 8 0
D 7 7 50
и так получается тут горел 20 секунд да и плюс те 44 выходит результат 64.
вот сделал програмку очень понятную и сразу понятно где ошибка есть вот она
program sviesoforas;
var n,i,j: integer;
 a:array [1..1001] of char;
 val,min,sek: array [1..1001] of  integer;
 b,c,d:integer;
pradDuom,
rezult: text;
begin
d:=0;
assign (pradDuom, 'duom.TXT');
assign (rezult, 'rez.TXT');
reset (pradDuom);
rewrite (rezult);
readln (pradDuom, n);
writeln(n);
for i := 1 to n do
begin
readln(pradDuom, a[i],val[i],min[i],sek[i]);
writeln(a[i],' ',val[i],' ',min[i],' ',sek[i]);
end;
for  i := 1 to n do
for  j :=1+i to n do
if a[i]<>a[j] then
               if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]=sek[j])
                then begin d:=d+30;
writeln(' a ',val[i],' ',min[i],' ',sek[i],' = ',val[j],' ',min[j],' ',sek[j],' ravno sekund ',d) 
end
                else
                 if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]<sek[j])
                  then begin d:=d+((sek[i]+30)-sek[j]); 
writeln(' b ',val[i],' ',min[i],' ',sek[i],' = ',val[j],' ',min[j],' ',sek[j],' ravno sekund ',d) 
end
                  else if (val[i] = val[j]) and (min[i]-min[j]=1) and (sek[j]>sek[i])
                        then
                          begin sek[j]:=sek[j]+30;
                            if sek[j]>60
                             then sek[j]:=sek[j]-60; min[j]:=min[j]+1;
                               if (min[i]-min[j]=0) and (sek[j]>sek[i])
                                then d:=d+((sek[i]+30)-sek[j]); sek[j]:=sek[j]+30; min[j]:=min[j]-1; 
writeln(' c ',val[i],' ',min[i],' ',sek[i],' = ',val[j],' ',min[j],' ',sek[j],' ravno sekund ',d);
                               end;
                  


                     writeln(d);
readln;
end.

вот еще другую сделал тожесамая ошибка
program sviesoforas;
var n,i,j: integer;
 a:array [1..1001] of char;
 val,min,sek: array [1..1001] of  integer;
 b,c,d:integer;
pradDuom,
rezult: text;
begin
d:=0;
assign (pradDuom, 'duom.TXT');
assign (rezult, 'rez.TXT');
reset (pradDuom);
rewrite (rezult);
readln (pradDuom, n);
writeln(n);
for i := 1 to n do
begin
readln(pradDuom, a[i],val[i],min[i],sek[i]);
writeln(a[i],' ',val[i],' ',min[i],' ',sek[i]);
end;
for  i := 1 to n do
for  j :=1+i to n do
if a[i]<>a[j] then
               if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]=sek[j])
                then d:=d+30
                else
                 if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]<sek[j])
                  then d:=d+((sek[i]+30)-sek[j])
                   else
                    if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]>sek[j])
                     then d:=d+(sek[i]-(sek[j]+30))
                     else
                      if (val[i]=val[j])
                       then
                        begin
                         if (min[i]-min[j]=1)
                          then
                           begin
                            min[i]:=min[i]-1; sek[i]:=sek[i]+60;
                             if (min[i]-min[j]=0)
                              then
                               if (sek[i]-sek[j]>0) then   d:=d+(sek[i]-sek[j]); writeln(d); 
writeln(' then ',val[i],' ',min[i],' ',sek[i],' = ',val[j],' ',min[j],' ',sek[j])
                           end
                          else
                           begin
                            min[j]:=min[j]-1; sek[j]:=sek[j]+60;
                            if (min[j]-min[i]=0)
                             then
                              if (sek[j]>sek[i])
                               then
                                if (sek[j]-sek[i]<30)
                                 then d:=d+(sek[i]-(sek[j]+30));
                           end;
                           end;
                     writeln(d);
readln;
end.


посоветуйте как лутше сделать или исправьте эти программки.

8 задача Дан список владельцев автомобилей и их номера автомобилей. Надо по номеру автомобиля найти этого человека которому автомобиль принадлежит.
в файле duom.txt. написано на первой строке номер автомобиля которого найти нада на второй строке написан сколько в списке фамилий. фамилия может содержать до 20 символов номер 3 буквы латинские и 3 цифры от 1 до 999.
вот предоставили данные
const SK = 1000;
type savin = record
pavarde: string[20];
num_raid: string[3];
num_sk: 1..999
end;
sarasas = array [1..SK] of savin;

и все номера автомобилей будут по порядку идти
AAA001
AAA002
AAA005
AAA006
...
AAA999
AAB002
...
и еще списак можетбыть от 1 до 1000 людей
данные записать в файл rez.txt.
пример
KVL578
6
Petraitis ABC321
Petkeviciene BJU500
Jonaitis DKG512
Antanaitis KVL578
Zemaityte KVL644
Bartkus VVV255

результат фамилия владельца автомобиля Antanaitis
вот я зделал простую программу эту все правильно выводит
вот
program automobilis;
const SK = 1000;
type savin = record
pavarde: string[20];
num_raid: string[3];
num_sk: 1..999
end;
sarasas = array [1..SK] of savin;
var
a:string[3];
n,i,s:integer;
c:sarasas;
p:text;
begin
assign (p, 'duom.TXT');
reset (p);
readln (p, a,n);
writeln(a,' ',n);
readln(p, s);
writeln(s);
for i:=1 to s do
begin
readln(p,c[i].pavarde,c[i].num_raid,c[i].num_sk);
writeln(c[i].pavarde,'  ',c[i].num_raid,' ',c[i].num_sk);
end;
writeln;
for i:=1 to s do
if (c[i].num_raid=a) and  (c[i].num_sk=n) then writeln( c[i].pavarde);
readln;
end.


потом я эту программу перепишу в двоичный поиск сделаю.

непонятно мне следущее
Вместе с 7 и 8 заданиями вместе должно быть выложена программа генерирующая случайное условия соответствующую первичным набором данных (случайный тест) в котором должен быть хоть один искомый обьект.
вот все ого как это так может обесните.
и еще эти задания должны быть записаны в файлы lapsi107.pas и lapsi108.pas генерирующие программы должны быть записаны в файлы apsi107gen.pas и lapsi108gen.pas .
во как даже может мне обьясните что за генераторы и как их сделать .


Добавлено через 2 мин.
ого сколько много написал я. если что нибуть непонятно то спросите уж извините за перевод с литовского на русский
Lapp
Цитата(maksimla @ 17.12.2008 15:49) *
вот сделал програмку очень понятную
Вот ЭТО ты называешь понятным??.. blink.gif Ты, наверное, шутишь..

Вот, смотри, я немного поработал над твоим кодом (первый текст). Я понятия не имел, что ты там делаешь, я даже не читал задание. Просто сразу стало ясно, что код нуждается в "причесывании". Когда причесал, стало видно, что многие твои условия лишние. В конечном итоге вышло вот, что:
program sviesoforas;
var
  n,i,j: integer;
  a: array [1..1001] of char;
  val,min,sek: array [1..1001] of  integer;
  b,c,d: integer;
  pradDuom,rezult: text;

begin
  d:=0;
  assign (pradDuom, 'duom.TXT');
  assign (rezult, 'rez.TXT');
  reset (pradDuom);
  rewrite (rezult);
  readln (pradDuom, n);
  writeln(n);
  for i := 1 to n do begin
    readln(pradDuom, a[i],val[i],min[i],sek[i]);
    writeln(a[i],' ',val[i],' ',min[i],' ',sek[i]);
  end;
  for  i := 1 to n do for j :=1+i to n do begin
    if (a[i]<>a[j]) and (val[i]=val[j]) and (min[i]=min[j]) then begin
      if sek[i]=sek[j] then begin
        d:=d+30;
        Write('a ');
      end
      else if sek[i]<sek[j] then begin
        d:=d+((sek[i]+30)-sek[j]);
        Write('b ')
      end
      else begin
        sek[j]:=sek[j]+30;
        if sek[j]>60 then sek[j]:=sek[j]-60;
        min[j]:=min[j]+1;
        d:=d+((sek[i]+30)-sek[j]);
        sek[j]:=sek[j]+30;
        min[j]:=min[j]-1;
        Write('c ')
      end;
      Writeln(val[i],' ',min[i],' ',sek[i],' = ',val[j],' ',min[j],' ',sek[j],' ravno sekund ',d)
    end
  end;
  writeln(d);
  readln;
end.

Вот теперь можно начинать вникать в смысл.. smile.gif

P.S.
Ты извини, я твой исходный код тоже порезал немного, а то из-за длинный строк в коде читать само сообщение было практически невозможно
maksimla
извините но серовно тут неправильно результат выводит 30 а надо 44 во первичные данные
пример
первичные данные
8
K 21 1 59
D 7 8 0
K 13 55 13
D 13 54 59
D 21 2 29
K 7 8 0
D 7 7 50
K 13 55 30
результат
44
maksimla
вот свой код исправил я как мне приснилось ночью ))
пока кажется работает все правильно с этими данными но может с другими данными плохо будет а?
вот
program sviesoforas;
var
  n,i,j: integer;
  a:array [1..1001] of char;
  val,min,sek: array [1..1001] of  integer;
  d:integer;
  pradDuom,rezult: text;
begin
  d:=0;
  assign (pradDuom, 'duom.TXT');
  assign (rezult, 'rez.TXT');
  reset (pradDuom);
  rewrite (rezult);
  readln (pradDuom, n);
  for i := 1 to n do begin
   readln(pradDuom, a[i],val[i],min[i],sek[i]);
  end;
  for  i := 1 to n do for  j :=1+i to n do
   if (a[i]<>a[j]) and (a[i]<>' ') and (a[j]<>' ')
    then if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]=sek[j])
       then begin d:=d+30; a[i]:=' '; a[j]:=' '; end
        else if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]<sek[j])
             then begin d:=d+((sek[i]+30)-sek[j]); a[i]:=' '; a[j]:=' '; end
             else if (val[i] = val[j]) and (min[i]-min[j]=1) and (sek[j]>sek[i])
                   then begin
                         sek[j]:=sek[j]+30;
                         if sek[j]>60
                          then sek[j]:=sek[j]-60; min[j]:=min[j]+1;
                           if (min[i]-min[j]=0) and (sek[j]>sek[i])
                            then d:=d+((sek[i]+30)-sek[j]); sek[j]:=sek[j]+30; min[j]:=min[j]-1; a[i]:=' '; a[j]:=' ';
                               end;
  write(rezult,d);
  close(pradduom);
  close(rezult);
end.
maksimla
все я больше запутался и уже немогу решать голова кругом идет wacko.gif
сматрел примеры если
данные будут
13 55 00
13 54 59
и другие данные
13 55 13
13 54 59
и еще наоборот и вот что получается пока неправильно
program sviesoforas;
var
  n,i,j: integer;
  a:array [1..1001] of char;
  val,min,sek: array [1..1001] of  integer;
  d,r:real;
  pradDuom,rezult: text;
begin
  d:=0;
  assign (pradDuom, 'duom.TXT');
  assign (rezult, 'rez.TXT');
  reset (pradDuom);
  rewrite (rezult);
  readln (pradDuom, n);
  for i := 1 to n do begin
   readln(pradDuom, a[i],val[i],min[i],sek[i]);
  end;
  for  i := 1 to n do for  j :=1+i to n do
   if (a[i]<>a[j]) and (a[i]<>' ') and (a[j]<>' ')
    then if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]=sek[j])
       then begin d:=d+30; a[i]:=' '; a[j]:=' '; end
        else if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]<sek[j])
             then begin d:=d+((sek[i]+30)-sek[j]); a[i]:=' '; a[j]:=' '; end
          else  if (val[i]=val[j]) and (min[i]=min[j]) and (sek[i]>sek[j])
             then begin d:=d+((sek[j]+30)-sek[j]); a[i]:=' '; a[j]:=' '; end
             else if (val[i]=val[j]) and (min[i]-min[j]=1) and (sek[i]<sek[j])
                      then begin sek[j]:=sek[j]+30;
                       if sek[j]>=60 then sek[j]:=sek[j]-60; min[j]:=min[j]+1;
                         if (val[i]=val[j]) and (min[i]=min[j])
                         then if sek[i]<sek[j]
                          then begin r:=(sek[j]-(sek[i]+30)); d:= d+(sqrt(sqr(r))); a[i]:=' '; a[j]:=' '; end ; end;

                                    
  write(rezult,d:0:0);
  close(pradduom);
  close(rezult);
end.



может чтонибуть подскажете или дапишите или перепишите програмку а то мне в воскресение это здавать надо будет
maksimla
K 13 55 13
D 13 54 59
непонел вот услал уже и тут получается 16 секунд наверное ужас а в примере написано что 14 секунд получается запутался нечего непойму уже
Lapp
Цитата(maksimla @ 20.12.2008 11:31) *
запутался нечего непойму уже
Конечно, запутаешься тут. Ты вот просишь помочь, а советов не слушаешь. Я же тебе сказал: чтобы разобраться, надо программу
а) правильно отформатировать;
б) разобраться с логикой и выкинуть лишние условия.
И я тебе это даже сдалал! Но ты не внимаешь советам. В твоей логике черт ногу сломит. Я убрал все лишнее и отформатировал. Суть программы осталась ТА ЖЕ САМАЯ (если я не ошибся smile.gif). Ты посмотри и разберись. Когда поймешь, что именно я сделал - думаю, поймешь и где ошибка. Если нет - я помогу.
maksimla
так я примерно понел это что написали
program sviesoforas;
var
  n,i,j: integer;
  a: array [1..1001] of char;
  val,min,sek: array [1..1001] of  integer;
  d: integer;
  pradDuom,rezult: text;

begin
  d:=0;
  assign (pradDuom, 'duom.TXT');
  assign (rezult, 'rez.TXT');
  reset (pradDuom);
  rewrite (rezult);
  readln (pradDuom, n);
  writeln(n);
  for i := 1 to n do begin
    readln(pradDuom, a[i],val[i],min[i],sek[i]);
    writeln(a[i],' ',val[i],' ',min[i],' ',sek[i]);
  end;
{да признаю что этот лутше код написан и тут все понятно }
  for  i := 1 to n do for j :=1+i to n do begin
    if (a[i]<>a[j]) and (val[i]=val[j]) and (min[i]=min[j]) then begin
      if sek[i]=sek[j] then begin
        d:=d+30;
        Write('a ');
      end
      else if sek[i]<sek[j] then begin
        d:=d+((sek[i]+30)-sek[j]);
        Write('b ')
      end
{ конец этого кода}
{а вот тут не выполняется после  else чегото почему не выполняется ? }
      else begin
        sek[j]:=sek[j]+30;
        if sek[j]>60 then sek[j]:=sek[j]-60;
        min[j]:=min[j]+1;
        d:=d+((sek[i]+30)-sek[j]);
        sek[j]:=sek[j]+30;
        min[j]:=min[j]-1;
        Write('c ')
      end;
      Writeln(val[i],' ',min[i],' ',sek[i],' = ',val[j],' ',min[j],' ',sek[j],' ravno sekund ',d)
    end
  end;
  writeln(d);
  readln;
end.

Lapp
Цитата(maksimla @ 20.12.2008 12:46) *
{а вот тут не выполняется после else чегото почему не выполняется ? }
Должно выполняться при sek[i]>sek[j] . Почему ты думаешь, что не выполняется? Если не выполняется, то значит учловие sek[i]>sek[j] никогда не осуществляется.
maksimla
потомучто написал это и не видел букв я вот и поэтому
else begin
      writeln('лl');
        sek[j]:=sek[j]+30;
        if sek[j]>60 then begin sek[j]:=sek[j]-60;
        min[j]:=min[j]+1;
        d:=d+((sek[i]+30)-sek[j]);
        sek[j]:=sek[j]+30;
        min[j]:=min[j]-1;
        Write('c ')
        end;
      end; 


Айра
Цитата
...и выкинуть лишние условия. И я тебе это даже сдалал!

Lapp, по-моему, ты убрал из его кода слишком много "лишнего") вариант, когда минуты разные вообще не рассматривается теперь.. и в ситуации, например, K 7 5 55 и D 7 6 12 до сравнения секунд дело просто не дойдет.. sad.gif
Lapp
Цитата(Айра @ 20.12.2008 13:32) *
ты убрал из его кода слишком много лишнего)
Хм.. в самом деле? unsure.gif интересно, как это произошло.. что-то упустил?
ок, я посмотрю.

Айра а ты не найдешь? rolleyes.gif очень спать хочется... smile.gif


Добавлено через 1 мин.
Цитата(Айра @ 20.12.2008 13:32) *

Lapp, по-моему, ты убрал из его кода слишком много "лишнего") вариант, когда минуты разные вообще не рассматривается теперь.. и в ситуации, например, K 7 5 55 и D 7 6 12 до сравнения секунд дело просто не дойдет.. sad.gif


Кстати, а почему "теперь"? ты уверена, что он рассматривался до того?
впрочем, вполне возможно.. smile.gif
maksimla
вот кажется сделал я до конца можете проверить очень большой этот текст
program sviesoforas;
var
  n,i,j: integer;
  a: array [1..1001] of char;
  val,min,sek: array [1..1001] of  integer;
  d: integer;
  pradDuom,rezult: text;
begin
  d:=0;
  assign (pradDuom, 'duom.TXT');
  assign (rezult, 'rez.TXT');
  reset (pradDuom);
  rewrite (rezult);
  readln (pradDuom, n);
  for i := 1 to n do begin
    readln(pradDuom, a[i],val[i],min[i],sek[i]);
  end;
  for  i := 1 to n do
  for j :=1+i to n do
  begin
    if (a[i]<>a[j]) and (a[i]<>' ') and (a[j]<>' ')
     then
      if(val[i]=val[j]) and (min[i]=min[j])
       then
        begin
         if sek[i]=sek[j]
          then
           begin
            d:=d+30;
            a[i]:=' ';
            a[j]:=' ';
            end
          else
           if sek[i]<sek[j]
            then
             begin
              d:=d+((sek[i]+30)-sek[j]);
              a[j]:=' ';
              a[i]:=' ';
             end
            else
             if sek[i]>sek[j]
              then
               begin
                d:=d+((sek[j]+30)-sek[i]);
                a[i]:=' ';
                a[j]:=' ';
               end;
        end
        else  if  (val[i]=val[j]) and (min[i]-min[j]=1)
               then
                begin
                 if sek[j]>sek[i]
                  then
                   begin
                    sek[j]:=sek[j]+30;
                    if sek[j]>60
                     then
                      begin
                       sek[j]:=sek[j]-60;
                       min[j]:=min[j]+1;
                        if  (val[i]=val[j]) and (min[i]=min[j]) and (sek[j]>sek[i])
                         then
                          begin
                          d:=d+((sek[i]+30)-sek[j]);
                          a[i]:=' ';
                          a[j]:=' ';
                          end;
                      end;
                   end;
                end
               else
                if (min[j]-min[i]=1)
                 then
                  begin
                  if sek[i]>sek[j]
                   then
                    begin
                     sek[i]:=sek[i]-60;
                     min[i]:=min[i]+1;
                      if  (val[i]=val[j]) and (min[i]=min[j]) and (sek[j]<sek[i])
                         then
                          begin
                           d:=d+((sek[j]+30)-sek[i]);
                           a[i]:=' ';
                           a[j]:=' ';
                          end
                    end
                  end
                  else
                   if val[i]-val[j]=1
                    then
                     begin
                      sek[j]:=sek[j]+30;
                       if sek[j]>=60
                        then
                         begin
                          sek[j]:=sek[j]-60;
                          min[j]:=min[j]+1;
                          if min[j]>=60
                           then
                            begin
                             min[j]:=min[j]-60;
                             val[j]:=val[j]+1;
                             if (val[i]=val[j]) and (min[i]=min[j]) and (sek[j]>sek[i])
                              then
                               begin
                                 d:=d+(sek[j]-sek[i]);
                                 a[i]:=' ';
                                 a[j]:=' ';
                               end;
                            end;
                         end;
                     end
                    else
                     if val[j]-val[i]=1
                     then
                     begin
                      sek[i]:=sek[i]+30;
                       if sek[i]>=60
                        then
                         begin
                          sek[i]:=sek[i]-60;
                          min[i]:=min[i]+1;
                          if min[i]>=60
                           then
                            begin
                             min[i]:=min[i]-60;
                             val[i]:=val[i]+1;
                             if (val[j]=val[i]) and (min[j]=min[i]) and (sek[i]>sek[j])
                              then
                               begin
                                 d:=d+(sek[i]-sek[j]);
                                 a[i]:=' ';
                                 a[j]:=' ';
                               end;
                            end;
                         end;
                     end

                  end;
  writeln(rezult,d);
  close(pradduom);
  close(rezult);
end.
Айра
0. думаю, при вычислении d нужно проверять, чтоб оно не было отрицательным..
например, время 8.7.10 8.7.50 удовлетворяет условиям if(val[i]=val[j]) and (min[i]=min[j]) и if sek[i]<sek[j] однако d при вычислении получится = -10, а нам такое считать не надо же?
1.
       else  if  (val[i]=val[j]) and (min[i]-min[j]=1)
               then
                begin
                 if sek[j]>sek[i]
                  then
                   begin
                    sek[j]:=sek[j]+30;
                    if sek[j]>60
                     then
                      begin
                       sek[j]:=sek[j]-60;
//здесь мне кажется достаточным проверить только (sek[j]>sek[i]) и по результату считать..
//min[j]:=min[j]+1; тогда тоже считать не надо
                       min[j]:=min[j]+1;
                        if  (val[i]=val[j]) and (min[i]=min[j]) and (sek[j]>sek[i])
                         then
                          begin
                          d:=d+((sek[i]+30)-sek[j]);
                          a[i]:=' ';
                          a[j]:=' ';
                          end;

2.
             if sek[i]>sek[j]
                   then
                    begin
                     sek[i]:=sek[i]-60;
                     min[i]:=min[i]+1;
                      if  (val[i]=val[j]) and (min[i]=min[j]) and (sek[j]<sek[i])

тут что-то не то, после этих действий у тебя sek[i] всегда будет отрицательной, а sek[j] - положительной.. здесь же должно быть аналогично предыдущему варианту, только i на j поменять..

[оффтоп]
>Айра а ты не найдешь? rolleyes.gif очень спать хочется... smile.gif
не только тебе)
>Кстати, а почему "теперь"? ты уверена, что он рассматривался до того?
>впрочем, вполне возможно.. smile.gif
вполне возможно yes2.gif
[/оффтоп]

volvo
Цитата
результат
44
обьяснение
7 8 0 загорелся свет в обоих частях и горел 30 секунд
D 13 54 59 в правой загорелся
K 13 55 13 в левой загорелся и горел в месте 14 секунд.
Общее горения 44 секунды.

Можно кое-что уточнить? Почему 14 секунд? Левый светофор загорелся через 14 секунд после правого, это я вижу... Время горения каждого = 30 секунд, это тоже ясно... Но тогда получается, что вместе светофоры горели 16 секунд, после чего в 13:55:29 правый погас... Итого общее время горения = 46

Вот программка, которая пожирает на треть меньше памяти:
program sviesoforas;
var
  n, i, j: integer;
  a: array[1 .. 1001] of char;
  ch: char;
  value: array[1 .. 1000] of longint;
  d, T:longint;
  pradDuom, rezult: text;

function to_sec(h, m, s: integer): longint;
begin
  to_sec := longint(h) * 3600 + m * 60 + s;
end;

var
  ch_side: char;
  h, m, s: integer;
  diff, left_until, right_until: longint;
begin
  d:=0;
  assign (pradDuom, 'duom.TXT');
  assign (rezult, 'rez.TXT');
  reset (pradDuom);
  rewrite (rezult);
  readln (pradDuom, n);

  for i := 1 to n do begin
    readln(pradDuom, ch_side, h, m, s);
    value[i] := to_sec(h, m, s);
    a[i] := ch_side;
  end;

  for i := 1 to n do
    for j := n downto i + 1 do
      if value[j - 1] > value[j] then begin
        T := value[j - 1]; value[j - 1] := value[j]; value[j] := T;
        ch := a[j - 1]; a[j - 1] := a[j]; a[j] := ch;
      end;

  for i := 1 to n do begin
   if a[i] = 'D' then begin
     right_until := (value[i] + 30) mod 86400;
     diff := (left_until - value[i]) mod 86400;
     if (diff > 0 ) and (diff <= 30) then d := d + diff;
   end
   else begin
     left_until := (value[i] + 30) mod 86400;
     diff := (right_until - value[i]) mod 86400;
     if (diff > 0) and (diff <= 30) then d := d + diff;
   end;
  end;

  { writeln(d); }
  write(rezult, d);
  close(pradduom);
  close(rezult);
end.


Изменим задачу:
Цитата
10
K 21 1 59
D 7 8 0
K 13 55 13
D 13 54 59
D 21 2 29
D 14 55 0
K 7 8 0
D 7 7 50
K 14 55 20
K 13 55 30
, то есть, добавлено еще 2 нажатия: справа в 14:55:00 и слева - в 14:55:20. То есть, добавлено еще 10 секунд совместного горения. Результат работы программы = 56, как и ожидалось...
maksimla
спасибо но может мне обьясните эту задачку как вы сделали ? и почему меньше ресурсов требует и от куда такие цифры взяли?

program sviesoforas;
var
  n, i, j: integer;
  a: array[1 .. 1001] of char;
  ch: char;
  value: array[1 .. 1000] of longint;
  d, T:longint;
  pradDuom, rezult: text;

function to_sec(h, m, s: integer): longint;
begin
  to_sec := longint(h) * 3600 + m * 60 + s;
end;

var
  ch_side: char;
  h, m, s: integer;
  diff, left_until, right_until: longint;
begin
  d:=0;
  assign (pradDuom, 'duom.TXT');
  assign (rezult, 'rez.TXT');
  reset (pradDuom);
  rewrite (rezult);
  readln (pradDuom, n);

  for i := 1 to n do begin
    readln(pradDuom, ch_side, h, m, s);
    value[i] := to_sec(h, m, s);
    a[i] := ch_side;
  end;

тут вроде так все понятно только зачем написали два var?


for i := 1 to n do
    for j := n downto i + 1 do
      if value[j - 1] > value[j] then begin
        T := value[j - 1]; value[j - 1] := value[j]; value[j] := T;
        ch := a[j - 1]; a[j - 1] := a[j]; a[j] := ch;
      end;

  for i := 1 to n do begin
   if a[i] = 'D' then begin
     right_until := (value[i] + 30) mod 86400;
     diff := (left_until - value[i]) mod 86400;
     if (diff > 0 ) and (diff <= 30) then d := d + diff;
   end
   else begin
     left_until := (value[i] + 30) mod 86400;
     diff := (right_until - value[i]) mod 86400;
     if (diff > 0) and (diff <= 30) then d := d + diff;
   end;
  end;

а тут уже нечего непонел зачем сперва полследнее время смотрите а потом первое
и еще в компеляторе написали left_until неиспользуется можете обеснить поподробнее?
maksimla
а от куда взял число 86400?
volvo
Цитата
только зачем написали два var?
А какая разница? Хоть пять разделов Var сделай, от этого ничего не изменится... Я по привычке, чтоб далеко наверх не проматывать страницу, сделал еще один раздел, и там все определил... Хочешь - объедини.

Цитата
и почему меньше ресурсов требует
Ну, смотри: у тебя 3 массива по 1001 элементу (каждый Integer занимает по 2 байта), и еще 1001 Char (по одному байту). Всего примерно 7000 байт выделено. Я, вместо того, чтобы хранить и постоянно сравнивать 3 числа на каждое событие, записываю в один LongInt смещение от начала суток в секундах (у тебя в условии написано, что данные в файле хранятся только за сутки). Итого 1001 * 4 + 1001 * 1 = 5000 байт примерно. Вот тебе и экономия почти 2К.

Цитата
а тут уже нечего непонел зачем сперва полследнее время смотрите а потом первое
Хм.. Смотри:
// сначала сортируем смещения (а вместе с ними и соответствующие им буквы)
// обычным методом "пузырька", это должно быть понятно... Потому что события
// должны быть упорядочены по времени возникновения
for i := 1 to n do
    for j := n downto i + 1 do
      if value[j - 1] > value[j] then begin
        T := value[j - 1]; value[j - 1] := value[j]; value[j] := T;
        ch := a[j - 1]; a[j - 1] := a[j]; a[j] := ch;
      end;

// а вот теперь...
// пробегаемся по всему массиву данных и делаем вот что:
// запоминаем в переменной right_until время (в секундах от начала суток), 
// когда _погаснет_ правый светофор (посчитать очень просто, мы же знаем,
// когда он загорелся, правда? +30 и всего делов),

// а в переменной left_until - время, когда погаснет светофор левый.

  left_until := 0; right_until := 0; // <--- Чтобы убрать предупреждение компилятора

  for i := 1 to n do begin
   if a[i] = 'D' then begin // нажата кнопка правого?
     right_until := (value[i] + 30) mod 86400; // value[i] - время нажатия, погаснет через 30 секунд
     diff := (left_until - value[i]) mod 86400; // так, правый светофор горит... А может, и левый ЕЩЕ горит?

     // diff - это разница между текущим временем и временем гашения левого светофора. Если она 
     // положительная и меньше 30, значит, на время diff загорятся ОБА светофора сразу, значит,
     // надо прибавить эту разницу к итоговому времени
     if (diff > 0 ) and (diff <= 30) then d := d + diff;
   end
   else begin // нажата кнопка левого?
     left_until := (value[i] + 30) mod 86400; // и он погаснет через 30 секунд

     // здесь делаем то же самое, что и выше, но поскольку это - нажатие на левую кнопку,
     // то ищем разницу со временем гашения правого светофора...
     diff := (right_until - value[i]) mod 86400;
     if (diff > 0) and (diff <= 30) then d := d + diff;
   end;
  end;

Вот, собственно, и вся идея. А 86400 - это количество секунд в сутках (60 сек * 60 мин * 24 часа), я делал mod 86400 для того, чтобы никакие смещения и разницы не превышали этого числа, это может помочь правильно дать ответ даже тогда, когда время в файле записано чуть больше, чем за сутки. Если сильно раздражает - можешь попробовать убрать это получение остатка. В подавляющем большинстве случаев результаты и так будут меньше 86400.

Цитата
и еще в компеляторе написали left_until неиспользуется можете обеснить поподробнее?
Не было такого никогда. Там написано, что "компилятору кажется, что переменная может быть использована до ее инициализации." Но этого произойти не может, переменная глобальная, в любом случае инициализируется нулем. Для того, чтобы убрать это предупреждение - добавь строчку, присваивающую обоим переменным значение 0 после сортировки, я показал в коде, куда именно.
maksimla
непонятно мне следущее
Вместе с 7 и 8 заданиями вместе должно быть выложена программа генерирующая случайное условия соответствующую первичным набором данных (случайный тест) в котором должен быть хоть один искомый обьект.
что тут надо сделать непонял может объясните?
[color=#FF9900]


каждый Integer занимает по 2 байта чего жесткого диска памяти или ddr ram ?
и какая теперь разница если этой памяти много есть?
а как подсчитать сколько mhz потребует программа или как для этой программы сколько hz потребуется ?
мне просто интересно как считают так и узнают какие минимальные требования чтобы программа пошла нормально работать ?
volvo
Цитата
каждый Integer занимает по 2 байта чего жесткого диска памяти или ddr ram ?
Имеется в виду, когда программа запущена - это в памяти...

Цитата
и какая теперь разница если этой памяти много есть?
Это тебе кажется, что ее много. Ты загляни в мой профиль, посмотри на характеристики компьютера. Так вот при всем при этом если мне удастся уменьшить количество памяти, пожираемое нашим проектом на 5 (повторяю, пять) Кб, то 5% прибавка к зарплате мне обеспечена... Борьба за байты идет, а не за килобайты.

А для паскаля это вообще критическая вещь: сколько б у тебя памяти не было, использовать статически ты можешь всего 64К (ибо только один сегмент данных может быть в программе), и с использованием динамической памяти - всего до 640К. Ты думаешь, это так много? Уверяю тебя, это совсем не так... Ну, в принципе, дело-то твое, если тебе удобнее разбираться с кучей массивов и делать 70-строчные if/else, то делай по своему, кто ж против... Тебе говорят, как правильнее делать - ты опять ничего слушать не хочешь... Делай как знаешь, чего спрашиваешь тогда?

Цитата
программа генерирующая случайное условия соответствующую первичным набором данных (случайный тест) в котором должен быть хоть один искомый обьект.
что тут надо сделать непонял может объясните?
Объясняю: тебе надо написать программу, заполняющую файл duom.txt так, чтобы потом в результате запуска основной программы, ведущей подсчет, получилось ненулевое значение. Опять же, если сделать через смещения, как делал я - это займет 25 строк кода:

var
  value: array[1 .. 1000] of longint;
  letter: array[1 .. 1000] of char;

  i, n: integer;
begin
  randomize;
  n := random(995) + 6; { сколько выпадет, от 6 до 1000 }
  value[1] := random(500);
  if random > 0.5  then letter[1] := 'K' else letter[1] := 'D';


  for i := 2 to n do
    if random > 0.25 then begin { с вероятностью 75% - случайное значение }
      value[i] := 2 * random(43000);
      if random > 0.5  then letter[i] := 'K' else letter[i] := 'D';
    end
    else begin { с вероятностью 25% - значение, выдающее гарантированное решение }
      value[i] := value[i - 1] + random(30); { <--- Пауза между зажиганием меньше 30 секунд}
      if letter[i - 1] = 'K'
        then letter[i] := 'D' else letter[i] := 'K'; { а светофоры в I-1 и I - _разные_ }
    end;

  for i := 1 to n do begin
    writeln(letter[i]:2, (value[i] div (60*60)):3,
      ((value[i] mod (60*60)) div 60):3, (value[i] mod 60):3);
  end;
end.
(записываешь эти результаты в файл, не забудь количество добавить, и тестируешь основную программу этим файлом...)
maksimla
зачем и что это дает
 value[1] := random(500);

как это понять random > 0.5

if random > 0.5  then letter[1] := 'K' else letter[1] := 'D';

и что записывается в первый массив

а что тут чего такие числы маненкие 0.25 для чего
 if random > 0.25 then begin { с вероятностью 75% - случайное значение }
	  value[i] := 2 * random(43000)

и от куда такие проценты то 75 то 25 то еще чтото

а зачем это если и так будет много чисел
else begin { с вероятностью 25% - значение, выдающее гарантированное решение }
      value[i] := value[i - 1] + random(30); { <--- Пауза между зажиганием меньше 30 секунд}
      if letter[i - 1] = 'K'
        then letter[i] := 'D' else letter[i] := 'K'; { а светофоры в I-1 и I - _разные_ }
    end;

maksimla
можете подсказать как сделать random буквы английские от a..z
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.