Back To Up
%>
 
     

Из упорядоченного массива — случайный

Первое число упорядоченного массива меняем со случайным числом следующим за ним, т.е. от 2 до n-го, второе число меняем с числом из диапазона 3, n и т.д.

Входные данные: 1 2 3 4 5 6 7 8 9 10

Выходные данные: 2 4 1 10 7 3 9 6 8 5

Program RandomArray; 
Uses CRT; 
Const n=10; 
Type a_type=array [1..n] of integer; 
Var a:a_type; 
m,x,i:integer; 
Begin 
ClrScr; 
randomize; 
{исходный массив} 
for i:=1 to n do a[i]:=i; 
for i:=1 to n do write(a[i]:3); 
writeln; 
for i:=1 to n-1 do begin 
{случайное число из диапазона i+1,n} 
m:=random(n-i-1)+i+1; 
{обмен i и m числа массива } 
x:=a[i]; a[i]:=a[m]; a[m]:=x 
end; 
for i:=1 to n do write(a[i]:3); 
readln 
End. 

Скачать эту программу

Самая длинная подпоследовательность в последовательности

В последовательности 0 и 1 найти длину самой длинной подпоследовательности 0, индекс ее начала и индекс ее конца. Длина последовательности задана.

Входные данные: n=10. 0 1 0 0 0 0 1 0 0 0

Выходные данные: 4 3 6

Program Sequence; 
Uses CRT; 
Const n=10; 
Var 
x:array [1..n] of integer; 
i,max,k,s:integer; 
Begin 
ClrScr; 
for i:=1 to n do begin 
{ввод и проверка данных} 
repeat 
write(i,' '); readln(x[i]); 
until (x[i]=0) or (x[i]=1); 
end; 
{вывод исходной последовательности} 
for i:=1 to n do 
write(x[i]); 
writeln; 
s:=0; max:=0; 
for i:=1 to n do 
if x[i]=0 then inc(s) 
else if s>max then 
begin 
max:=s; k:=i-1; s:=0 
end; 

{Если самая длинная 
одпоследовательность 
в конце последовательности} 
if s>max then 
begin 
max:=s; k:=n 
end; 
{вывод результата} 
writeln(max,' ',k-max+1,' ',k); 
readln 
End. 

Несколько календарных задач


Високосный год

Продолжительность тропического года (время между двумя весенними равноденствиями) составляет 365 суток 5 часов 48 минут 46 секунд. Различие в продолжительности тропического года и среднего юлианского календарного года (365,25 суток) составляет 11 минут 14 секунд. Из этих 11 минут и 14 секунд приблизительно за 128 лет складываются одни сутки.

По истечении столетий было замечено смещение дня весеннего равноденствия, с которым связаны церковные праздники. К XVI веку весеннее равноденствие наступало примерно на 10 суток раньше 21 марта, используемого для определения дня Пасхи.

Чтобы компенсировать накопившуюся ошибку и избежать подобного смещения в будущем, в 1582 году римский папа Григорий XIII провёл реформу календаря. Чтобы средний календарный год лучше соответствовал солнечному, было решено изменить правило високосных лет. По-прежнему високосным оставался год, номер которого кратен четырём, но исключение делалось для тех, которые были кратны 100. Отныне такие годы были високосными только тогда, когда делились ещё и на 400.

Иными словами, год является високосным, если он кратен 4 и при этом не кратен 100, либо кратен 400. Год не является високосным, если он не кратен 4, либо кратен 4, но при этом кратен 100 и не кратен 40 [1].

Отсюда функция опредляющая является ли год високосным или обычным:

Function LeapYear(y:integer):boolean; 
Begin 
if y mod 400 =0 then 
if y mod 100=0 then LeapYear:=true 
else LeapYear:=false 
else 
if y mod 4 =0 then LeapYear:=true 
else LeapYear:=false 
End; 

Количество дней от 1 января 1 года

Хотя григорианский календарь был введен 1582 г., а в некторых странах гораздо позднее, например в СССР в 1918 г., условно будем считать, что он действует с 1 января 1 года. Тогда число дней прошедших с этого дня до данной даты (D.M.Y) определяется так: меняем параметр i от 1 до Y-1, если i соответсвует обычному году, то в переменную s прибавляем 365, если - високосному, то в s прибавляем 366. Далее меняем параметр i от 1 до M-1, в s прибавляем число дней в месяцах (с учетом является ли Y високосным или обычным годом). Наконец в s прибавляем число D.

Program TaskCalendar; 
Uses CRT; 
Type date=record 
day,month,year:integer; 
end; 
Const 
dmm:array [1..12] of integer 
=(31,28,31,30,31,30,31,31,30,
31,30,31); 
Function
 NumberOfDays(yy:date):longint; 
Var y,i:integer; 
s:longint; 
Begin 
s:=0; 
for y:=1 to yy.year-1 do 
if (LeapYear(y)) then s:=s+366 
else s:=s+365; 
for i:=1 to yy.month-1 do 
if (LeapYear(yy.year)) and (i=2) then s:=s+29 
else s:=s+dmm[i]; 
s:=s+yy.day; NumberOfDays:=s 
End;

Олимпиадная задача

В сборнике олимпиадных задач, опубликованных А.С. Пономаренко в приложении к журналу «Информатика в школе», представлена следующая задача [2]:

Составить программу, которая определит все годы до 100 - летнего юбелея, когда вы будете праздновать день своего рождения в тот же день недели, когда родились.

Если бы не было вискосных лет, то календарь повторялся бы каждые 7 лет, так как остаток от деления 365 на 7 равен 1. Если в этом году некая дата приходится на среду, то в следующем году она придется на четверг, на среду огна придется через 7 лет. Наличие високосных лет приводит к тому, что календарь полностью повторяется через каждые 7*4=28 лет.

Используем тот факт, что 01.01.01 было воскресеньем. Для кадого дня 100 - летнего периода будем определять число дней прошедших с 01.01.01, далее будем определять остаток от деления прошедших числа дней на 7, если этот остаток 1- то данный день - воскресенье, если 2, то понедельник и т.д., если остаток 0 - то данный день - суббота. Применим введенные нами функции.

Program TaskCalendar1; 
Uses CRT; 
Type date=record 
day,month,year:integer; 
end; 
dw=array[0..6] of string[3]; 
Var d,d1:date; 
i,k,j:integer; 
Const 
dww:array [0..6] of string[3]= 
('Sat','Sun','Mon','Tue','Wen',
Thu','Fri'); 
dmm:array [1..12] of integer= 
(31,28,31,30,31,30,31,31,30,
31,30,31);


	  
 Function LeapYear(y:integer):boolean;
  Begin
  if y mod 400 =0 then
      if y mod 100=0 then 
	  LeapYear:=true
                  else LeapYear:=false
           else
 if y mod 4 =0  then LeapYear:=true
                else LeapYear:=false
  End;
  


	
  Function NumberOfDays(yy:date):longint;
  Var  y,i:integer;
       s:longint;
     Begin
  s:=0;
  for y:=1 to yy.year-1 do
    if (LeapYear(y)) then s:=s+366
                     else s:=s+365;
  for i:=1 to yy.month-1 do
    if (LeapYear(yy.year)) and 
	(i=2) then s:=s+29
                                else s:=s+dmm[i];
      s:=s+yy.day;   NumberOfDays:=s
  End;
Begin 
ClrScr; 
write('day ='); readln(d.day); 
write('month='); readln(d.month); 
write('year ='); readln(d.year); 
k:=NumberOfDays(d) mod 7; 
yy:=d.year; d1:=d; 
for i:=d.year to d.year+100 do begin 
d1.year:=i; 
j:=NumberOfDays(d1) mod 7; 
if k=j then writeln(i:6,' ',dww[j]); 
end; 
readln; 
End.

Сохранить эту программу

Определение даты по числу дней от 1 января 1 года

Задачу можно представить как введение функции обратной NumberOfDays. Однако, мы введем процедуру, которая по количесву дней с 1 января 1 г. вычисляет дату.

Сначала из числа дней y будем вычитать 365/366 дней и считать число лет d.year пока не получим отрицательное число, прибавим к нему последнее вычитаемое и число лет уменьшим на 1. Если оставшееся число дней y будет меньше 31, то сразу выводим month=1 и y. Если это не так, то начинаем счет месяцев, вычитая из y число дней в месяце. Если в процессе счета полцчим month=13, то присвоим month значение 1. Счет месяцев будем вести до тех пор пока y остается больше 0. Скорректируем y на число дней в последнем месяце, а число месяцев уменьшим на 1. Если при этом month примет значение 0, то назначим ему значение 12.


Procedure 
DateN(y:longint; var d:date); 
Var 
dy:integer; 
Begin 
with d do begin 
year:=1; 
{счет числа лет} 
repeat 
if (LeapYear(year)) then dy:=366 
else dy:=365; 
y:=y-dy; 
year:=year+1 
until (y<=0); 
{корректировка числа лет} 
y:=y+dy; year:=year-1; 
{счет числа месяцев} 
month:=1; 
if y>31 then begin 
repeat 
if (LeapYear(year)) and (month=2) 
then dy:=29 
else dy:=dmm[month]; 
y:=y-dy; month:=month+1; 
if month>12 then month:=1; 
until (y<=0); 
{корректировка числа месяцев} 
y:=y+dy; month:=month-1; 
if month=0 then month:=12; 
end; 
d.day:=y 
end; 
End; 

Пятницы 13

Для данного года определим пятницы 13. Применим введенные нами функции.

Program TaskCalendar2; 
Uses CRT; 
Type date=record 
day,month,year:integer; 
end; 
dw=array[0..6] of string[3]; 

Var d:date; 
yb,ye,i:longint; 
k:integer; 
........................ 
Begin 
ClrScr; 
with d do begin 
write('year ='); readln(year); 
day:=1; month:=1; 
yb:=NumberOfDays(d); 
if (LeapYear(year)) then ye:=yb+366 
else ye:=yb+365; 
for i:=yb to ye do begin 
DateN(i,d); 
{день недели } 
k:=i mod 7; {если этот остаток =6, 
то это Fri} 
if (k=6) and (day=13) then 
writeln(13,' ',month,' Fri'); 
end; 
end; 
readln; 
End. 

Сохранить эту программу

Пасхалии

По заданному номеру года определить дату Пасхи по григорианскому календарю.

Пасхалия, сборник правил, на основании которых определяется день празднования пасхи. Поскольку эти правила требуют выполнения определённых условий, связанных с движением Земли вокруг Солнца (пасха должна быть вскоре после весеннего равноденствия), обращением Луны вокруг Земли (связь пасхи с полнолунием), с семидневной неделей (воскресенье), даты празднования пасхи непостоянны и перемещаются от года к году. Вследствие неидентичности правил П. разных религий, дни празднования пасхи у них не совпадают. Математическую теорию П. разработал К. Гаусс [3,4].

Program Easter;
Uses CRT;
Var g,y,i,j,l,month,day:integer;
Begin
ClrScr;
write('год='); readln(y);
g:=y mod 19;
i:=(g*19+15) mod 30;
j:=(y+y div 4+i) mod 7;
l:=i-j;
month:=3+(l+40) div 44;
day:=l+28-31*(month div 4);
day:=day+13; if day>31 then begin
          day:=day-31; month:=month+1;
                            end;


writeln('пасха ',day,'   ',month);
writeln('----------------------------------');


readln
End.


Источники:

1. Википедия. Високосный год
2. Информатика в школе: Приложение к журналу «Информатика и образование. №1 - 2006. -M.: Образование и информатика, 2006. - 112 с.
3. БСЭ. Пасхалии.
4. Малаховскй В.С. Введение в математику. - Калининград: Янтарный сказ, 2006. - 439 с.
<