Помощь - Поиск - Пользователи - Календарь
Полная версия: запутался в задачах чютчють одна норм а другая с ошибкой одной
Форум «Всё о Паскале» > 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®)); 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
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.