понеділок, 16 лютого 2015 р.

Вінницька обласна олімпіада з інформатики 2015

УМОВИ ЗАДАЧ ОЛІМПІАДИ
ЗАДАЧІ З ПРОГРАМУВАННЯ 


Задача Ticket2.   У місті Старопрограмістську  є усього 2 види міського транспорту: метро, де квиток на одну поїздку коштує 3 біта (ось така там грошова одиниця) і автобус, квиток на поїздку у якому коштує 2 біта. Можна придбати проїзний  квиток на обидва види транспорту за 60 біт, на метро – за 40 біт, а на автобус – за 30 біт. Усі проїзні квитки дають право  на необмежену кількість поїздок протягом місяця.  Яку мінімальну суму витратить на міський транспорт за місяць житель міста програміст Байтученко, якщо протягом місяця він планово має виконувати x поїздок на метро та y  поїздок на автобусі?
Технічні умови. Програма Ticket2 читає з пристрою стандартного введення два числа  x та  y через пропуск (0 <=x; y<= 100). Програма виводить на пристрій стандартного виведення мінімально можливу суму місячних витрат Байтученка (зрозуміло, у бітах).
Приклад
Введення            Виведення 
9 30                         57
Програма мовою Паскаль
PROGRAM  Ticket2;
var   x,y,s1,s2,sum:  integer;
 begin
   read(x,y);
    s1:=x*3;
    s2:=y*2;
     if s1>= 40   then   s1:=40;
     if s2>=30   then   s2:=30;
          if s1+s2>=60 then sum:=60
   else
           sum:=s1+s2;
   writeln(sum);
   end.








Задача Clock2015.  У вінницькому  магазині-музеї  «Колоніальні товари. Пан Заваркін та сини»  є N  годинників. Відомо, що К з них показують неправильний  час, а покази решти – правильні. Потрібно написати програму, яка дозволить відвідувачу магазина дізнатися  точний час.
Технічні умови. Програма Clock2015 читає з пристрою стандартного введення  2 числа N і K (0 <= K <= N<= 1000), а далі рядків по 2 числа – покази відповідного годинника. Перше число  - години (0-23),  друге – хвилини (0-59). Всі числа розділено пропусками. Програма виводить на пристрій стандартного виведення два числа – точний час у годинах та хвилинах.  Якщо однозначно точний час знайти неможливо – виведіть  -1.
Приклад
Введення             Виведення
5 3                        13 20                    
13 20
20 13
9 00
13 20
13 21


Програма мовою Паскаль
var i,m,k,res,n,p,j,r,h:longint;
 a:array[0..10000] of longint;
  begin
    read(n,k);
    p:=n-k;
      for i:= 1 to n do
        begin
          readln(h,m);
          m:=m+h*60;
          inc(a[m]);
        end;

      for j:= 0 to 10000 do
        if a[j]=p  then
         begin
         inc(r);
         res:=j;
         end;
     
 if r=1 then     begin
       write (res div 60,' ' );
          if res mod 60 <10 then write(0,res mod 60)
   else          write(res mod 60);
        end
else          write(-1);
       end.


 Задача Money.  У вас є достатня кількість монет 3-х номіналів a, b та c. Потрібно розрахуватися (тобто віддати продавцю) задану суму N максимально можливою кількістю монет. Монет продавцю потрібно дати не менше, ніж 2.  
Технічні умови. Програма Money читає з пристрою стандартного введення через пропуск чотири цілих числа N, a, b, c (1 ≤ N, a, b, c ≤ 40000) – N – задана сума і a, b, c – наявні номінали монет. Числа a, b і c можуть збігатися.
Вихідні дані: Виведіть одне число - максимально можливу кількість монет. Гарантується, що зазначену суму можна виплатити завжди.

Приклади
Введення
Виведення
Пояснення:
5 5 3 2
2
потрібно дати 2 монети: одна з них 2, друга 3.
7 5 5 2
2
потрібно дати 2 монети: одна з них 5, друга 2.




var
 g:array[-40000..41000] of LONGINT ;
 n,a,b,c,k,v1,v2,v3,i:longint;
  begin
   read(n,a,b,c);
    for i:= -n to n do   g[i]:=0;
     K:=0;
   g[a]:=1;
   g[b]:=1;
   g[c]:=1;
    for i:= 0 to n do

    if (i>=a) or (i>=b) or (i>=c)  then
       begin
        if (g[i-a]+1>g[i]) and (g[i-a]<>0) and(i>=a) then          g[i]:=g[i-a] +1;
            if (g[i-b]+1>g[i])  and (g[i-b]<>0)and (i>=b) then            g[i]:=g[i-b] +1;
            if (g[i-c]+1>g[i])   and (g[i-c]<>0) and (i>=c) then              g[i]:=g[i-c] +1;
        end;
       write(g[n]);
       end.


Задача  Castle.
Стародавній замок має прямокутну форму. Замок містить щонайменше дві кімнати. Підлогу замка можна умовно поділити на N клітин. Кожна така клітинка містить «0» або «1», які задають порожні ділянки та стіни замку відповідно. Напишіть програму, яка б знаходила площу найбільшої кімнати, яку можна утворити шляхом видалення стіни або її частини, тобто, замінивши лише одну «1» на «0». Видаляти зовнішні стіни заборонено.
Технічні умови. Програма  Castle  читає з пристрою стандартного введення «план замку». Перший рядок містить ціле число M, другий – ціле число  N – кількість рядків та кількість стовпчиків (3 ≤ M ≤ 1000, 3 ≤ N ≤ 1000). M наступних рядків містить по N нулів або одиниць, що йдуть поспіль (без пробілів). Перший та останній рядок, а також перший та останній стовпчик формують зовнішні стіни замку і складаються лише з одиниць. Програма виводить на пристрій   площу найбільшої кімнати, яка утвориться в разі видалення внутрішньої стіни.
Приклади:
Введення                       Виведення
6
8
11111111
10011001
10011001
11111001
10101001
11111111
                        10                            

9
12
111111111111
101001000001
111001011111
100101000001
100011111101
100001000101
111111010101
100000010001
111111111111
            
38                                     


Програма мовою Паскаль
var   n,m,i,j,color,sum,max:longint;
    c:char;

        a:array[-1..1001,-1..1001] of longint;
            s: longint;

   procedure dep(x,y,c:longint);
    begin

   inc(s) ;
    a[x,y]:=c;
     if (a[x,y+1]<>c)and (a[x,y+1]<>-1) then  dep(x,y+1,c);
        if( a[x,y-1]<>c)and (a[x,y-1]<>-1) then  dep(x,y-1,c);
          if (a[x+1,y]<>c) and (a[x+1,y]<>-1) then  dep(x+1,y,c);
            if (a[x-1,y]<>c) and (a[x-1,y]<>-1) then  dep(x-1,y,c);
    end;

      begin
        read(n,m);
        color:=1;
         for i := 1 to n do
         begin
         readln;
           for j:= 1 to m do
           begin
           read(c);
           a[i,j]:=ord(c)-48;
            if a[i,j]=1 then a[i,j]:=-1;
           end;
           end;
         for i:= 2 to n-1 do
             for j:= 2 to m-1 do
             begin
                 if a[i,j]=-1 then
                  begin
                           a[i,j]:=0;
                   dep(i,j,color);
                  if s>max then max:=s;
                   a[i,j]:=-1;
                   inc(color);
                             s:=0;
                                  end;
                        if a[i,j]=0 then
                  begin
                           a[i,j]:=0;
                   dep(i,j,color);
                   if s>max then max:=s;
                   inc(color);
                              s:=0;
                                   end;
                                   end;
        writeln(max);
           end.


Ще один варіант Програма мовою Паскаль через рекурсію

var n,m,i,j,p,x,y:integer;
    a:array[1..1000,1..1000] of longint;
    c:char;
    b:array[1..1000000] of longint;
    col,max,max1,cl,cp,cn,cw,nc,kc:longint;
    cx,cy:array[1..1000000] of integer;


{
procedure paint(q,w:integer);
 begin
   a[q,w]:=col;
   b[col]:=b[col]+1;
   if a[q-1,w]=0 then paint(q-1,w);
   if a[q+1,w]=0 then paint(q+1,w);
   if a[q,w-1]=0 then paint(q,w-1);
   if a[q,w+1]=0 then paint(q,w+1);
 end;}


 procedure paint(q,w:integer);
  begin
    nc:=1; kc:=1;
    cx[nc]:=q;
    cy[nc]:=w;
    while kc>=nc do
      begin
        x:=cx[nc];
        y:=cy[nc];
        a[x,y]:=col;
        b[col]:=b[col]+1;
        nc:=nc+1;
        if a[x-1,y]=0 then begin
                             kc:=kc+1;
                             cx[kc]:=x-1;
                             cy[kc]:=y;
                             a[x-1,y]:=col;
                           end;
        if a[x+1,y]=0 then begin
                             kc:=kc+1;
                             cx[kc]:=x+1;
                             cy[kc]:=y;
                             a[x+1,y]:=col;
                           end;
        if a[x,y-1]=0 then begin
                             kc:=kc+1;
                             cx[kc]:=x;
                             cy[kc]:=y-1;
                             a[x,y-1]:=col;
                           end;
        if a[x,y+1]=0 then begin
                             kc:=kc+1;
                             cx[kc]:=x;
                             cy[kc]:=y+1;
                             a[x,y+1]:=col;
                           end;

      end;
  end;






BEGIN
  readln(m);
  readln(n);
  for i:=1 to m do
    begin
       for j:=1 to n-1 do
         begin
           read(c);
           val(c,a[i,j],p);
         end;
       readln(c);
       val(c,a[i,n],p);
    end;



  col:=1;
  for i:=2 to m-1 do
    for j:=2 to n-1 do
       if a[i,j]=0 then
                      begin
                       col:=col+1;
                       paint(i,j);
                      end;



  max:=0;
  for i:=2 to m-1 do
   for j:=2 to n-1 do
     if a[i,j]=1 then
             begin
                max1:=1;
                cl:=a[i,j-1]; cp:=a[i,j+1];
                cw:=a[i-1,j]; cn:=a[i+1,j];
                if cl>1
                   then max1:=max1+b[cl];
                if ((cp>1) and (cp<>cl))
                   then max1:=max1+b[cp];
                if ((cw>1) and (cw<>cl) and (cw<>cp))
                   then max1:=max1+b[cw];
                if ((cn>1) and (cn<>cl) and (cn<>cp) and (cn<>cw))
                   then max1:=max1+b[cn];

                if max1>max then max:=max1;

             end;


 write(max);



END.



понеділок, 9 лютого 2015 р.

Програма множення двох матриць розміром 2х2 мовою Паскаль





program mnozehya_matriz;
const n=2;
var
a:array[1..n,1..n] of real;
b:array[1..n,1..n] of real;
c:array[1..n,1..n] of real;
i,j: integer;
begin
writeln('    ');
writeln('    ');
writeln('    ');
for i:=1 to 2 do begin
for j:=1 to 2 do begin
a[i,j]:=int(random*10-5);
write(' a[', i, ';', j, ']=', a[i,j]);
writeln('    ');
end;
end;
 for i:=1 to 2 do begin
for j:=1 to 2 do begin
b[i,j]:=int(random*10-3);
write(' b[', i, ';', j, ']=', b[i,j]);
end;
end;
for i:=1 to 2 do begin
for j:=1 to 2 do begin
writeln('    ');

c[1,1]:=a[1,1]*b[1,1]+a[1,2]*b[2,1];
c[1,2]:=a[1,1]*b[2,1]+a[1,2]*b[2,2];
c[2,1]:=a[2,1]*b[1,1]+a[2,2]*b[2,1];
c[2,2]:=a[2,1]*b[1,2]+a[2,2]*b[2,2];
write(' c[', i, ';', j, ']=', c[i,j]);
end;
end;
end.

Правила для стратегічних рішень у проблемних ситуаціях

Правила для стратегічних рішень у проблемних ситуаціях

Математики весь час намагаються описати наше життя як формулу. Часом виходить дуже переконливо. Але це тільки до тих пір, поки в гру не вступають чисто людські  якості - совість, довіра, жага справедливості, егоїзм, альтруїзм. Тут математика перестає працювати і починається як мінімум психологія. Ми відібрали десять найяскравіших інтелектуальних ігор, в основі яких життя у всьому різноманітті її проявів
1. Математична гра «Дилема ув'язненого»: свідчити або мовчати?
Правила: «Уявіть, що ви спробували пограбувати банк. Але, на жаль, вас і вашого подільника зловили і розсадили по різних камерах. Слідчий пропонує угоду: ви даєте свідчення проти свого напарника і тоді отримуєте шанс на звільнення за допомогу слідству. У вас є чотири варіанти дій.
1. Ви погоджуєтеся і даєте свідчення. Ваш напарник мовчить. Тоді він отримує десять років, а ви виходите на свободу.
2. Ви колеться, і ваш напарник колеться. Тоді ви обидва отримуєте по два роки.
3. Ви гордо мовчите, але ваш напарник дає свідчення. Тоді на свободу виходить він, а ви отримуєте десять років.
4. Ви обоє мовчите, і через шість місяців вас відпускають за браком доказів.
І що ви обираєте? Слідчий уже відкриває двері вашої камери ...
Історія та застосування
Базову модель «Дилеми ув'язненого» запропонували в 1950 році американські математики Меррил Флад і Мелвін Дрешер, що працювали на дослідницьку корпорацію RAND. Ця гра була потрібна для прогнозування гонки ядерних озброєнь - в ролі ув'язнених виступали СРСР і США.
З тих пір гра стала дуже популярна серед математиків, філософів і психологів. Виходячи з військово-кримінальної обкладинки, можна виявити і багато інших прикладів. Ту ж гонку озброєнь зараз дуже нагадують рекламні кампанії. Постійне змагання в кількості рекламного контента неухильно збільшує витрати фірм. Відповідно, від припинення гонки виграли б усі сторони. Але якщо хтось віроломно порушить перемир'я, він виграє війну за споживача, а інші програють.
У США навіть проводилися змагання між командами університетів на кращу запрограмовану стратегію гри в «Дилему ув'язненого», де перемога присуджувалася за мінімальний термін ув'язнення за підсумками декількох раундів допитів. Перемогла програма, заснована на принципі «око за око»: вона надходила з кожним своїм напарником в точності так, як з нею надійшли ходом раніше. Але це все-таки математика, людське життя куди складніше.
Людські якості
У реальності ви навряд чи будете грабувати банки. А російські слідчі не стануть пропонувати такі угоди. Це модель, притча, метафора людських відносин.
Щоб сумарна покарання було найменшим, вигідніше мовчати обом. Тоді загальний термін відсидки складе всього рік - набагато менше, ніж при будь-якому іншому сценарії. Але наскільки ви довіряєте тому, з ким йшли на діло? А він вам? І що для вас означають його інтереси? Якою мірою ви готові ризикувати?
Основна проблема «Дилеми ув'язненого» - довіра. Саме через небажання довіряти іншому і виникає конфлікт інтересів, який звели в абсолют, наприклад, сценаристи серії хоррорів «Пила». Так, у п'ятій частині герої можуть звільнитися в прямому сенсі малою кров'ю, щоб вибратися з пастки. Але замість цього вони починають змагатися, що призводить до загибелі більшості з них.
---------------------------------------------------------
2. «Ультиматум»: скільки ви готові заплатити за справедливість?
Правила
Двом гравцям пропонується розділити між собою деяку суму грошей, припустимо 1000 рублів. Перший з них, що подає, пропонує свій варіант поділу, наприклад кожному по 500 рублів, або йому 800, а напарнику - 200 і т. Д. Другий гравець, який приймає, може або погодитися на запропоновані умови і отримати свою частку, або відкинути схему розділу . У другому випадку ніхто грошей не отримує - вони йдуть назад в банк.
Історія та застосування
Правила цієї гри вперше були сформульовані в 1982 році в Journal of Economic Behaviour and Organization для опису процесу переговорів. Проста в моделюванні і парадоксальна в результатах, вона швидко стала улюбленим об'єктом дослідження для вчених усього світу. Гра «Ультиматум» підходить під багато життєві ситуації. Наприклад, коли вирішується питання, яку частину прибутку пустити на зарплату співробітникам, а яку віддати власникам фірми.
Людські якості
Що б ви зробили на місці приймаючого? Якщо виходити з раціональності, то треба погоджуватися на будь-який варіант розділу грошей. Навіть якщо подаючий хоче забрати собі 990 рублів, все одно сперечатися не варто: 10 рублів все-таки більше, ніж нуль. Але крім раціональності є ще й справедливість.
У сотнях проведених експериментів подають найчастіше пропонують своїм напарникам від 50 до 30%. Десь в інтервалі від 30 до 20% приймаючі починають відмовлятися від угоди, вибираючи принцип «Так не діставайся ж ти нікому!».
Розуміння справедливості залежить від культури. Перуанські індіанці, наприклад, були схильні приймати практично будь-які пропозиції, а жителі Азії виявилися набагато педантично і незговірливість американців. В одному з експериментів, проведених в Індонезії, випробовувані відмовлялися навіть від сум, що становлять кілька їх місячних зарплат.
Взагалі, психологи чимало говорили на тему гри «Ультиматум». Виявилося, що на результати експерименту впливає безліч факторів: сексуальне збудження, вік, ступінь агресивності, рівень тестостерону і так далі.
У 2003 році в журналі Science з'явилася стаття про дослідження, в якому роботу головного мозку гравців у «Ультиматум» безперервно відстежували за допомогою МРТ. Виявилося, що у приймаючого після одержання пропозиції активізуються острівна частина головного мозку, верхні області лобової кори і поясна звивина. Перша з цих областей вважається відповідальною за обробку і формування негативної емоційної інформації, а інші дві - за когнітивні процеси самоконтролю і вибору. Результат цього протистояння стародавнього механізму емоцій і придбаного раціонального мислення і визначає остаточне рішення.
Експерименти дали несподівані результати. Піддослідним штучно блокували роботу раціональної лобової кори. Здавалося б, відпущені на свободу емоції повинні в сказі відкидати все несправедливі пропозиції. Але вийшло навпаки: гравці стали набагато більш поступливими і податливими, емоції гніву та образи поступилися вродженому почуттю наживи. Виходить, що та сама раціональна діяльність лобової кори і призводить до відхилення від розумної математичної стратегії, а уявлення про честь і справедливості змушують людей приймати виважено-невигідне рішення. Недарма в експериментах, проведених на групах аутистів, відсоток відмов був значно нижче. Позбавлені соціальних забобонів, вони набагато частіше слідували ідеальної математичної моделі.
- Взаємодія когнітивних і емоційних механізмів прийняття рішення і визначає раціональну поведінку людини, а порушення в будь-якому з них призводить до вибору неоптимальних стратегій. Ці дві системи також можуть конфліктувати, результатом чого є безліч прикладів, коли утилітарне мислення приводило до жахливих наслідків і прямо суперечило нормам моралі, - пояснює Анна Шестакова, старший науковий співробітник Центру нейрокогнітивних досліджень МГППУ.
3. «Трагедія громадського пастбища»: якщо всі вчинять так.
  Правила
Жителі села володіють загальним пасовищем. Якщо кожен буде пасти на ньому одну корову, то нічого страшного, трави вистачить. Якщо хтось захоче завести другу, то начебто теж все нормально: поле щось велике. Але якщо кожен стане випасати по дві корови, то трави на полі не вистачить, пасовище виснажиться, почнеться голод.
Історія та застосування
Цю модель запропонував Вільям Форстер Ллойд в 1833 році в книзі, присвяченій перенаселення.
- Ця трагедія громад часто відбувається в житті - розігрується класичний сценарій з теорії ігор. Прикладів тому маса: екологічні проблеми, пробки на дорогах - будь-яке місце, де людині здається, що на халяву можна непомітно нажитися за рахунок суспільства, - пояснює професор РЕШ Олексій Саватєєв.
За прикладами далеко йти не треба. У Москві, де пробки стали колосальною проблемою, а екологічна обстановка погіршується рік від року, жителі наполегливо ігнорують громадську акцію «День без автомобіля», що проходить з 2008 року. Більш того, за деякими даними, саме в цей день кількість заторів на дорогах особливо велике.
Статті з різними модифікаціями цієї гри з'являються в провідних наукових журналах типу Science і в наш час. Наприклад, є варіант експерименту під назвою «Суспільне благо». Ось як його описують вчені з Вищої школи економіки Діляра Валєєва і Марія Юдкевич: «Кожен з учасників спочатку наділяється певною сумою грошей. Кожен повинен приватно вирішити, яку частку цих особистих грошей він може інвестувати в суспільне благо. Вкладені в суспільне благо гроші збільшуються в кілька разів і діляться порівну. Група отримає максимальну вигоду, якщо кожен учасник інвестує всю свою початкову суму грошей. Однак гравці можуть ухилятися від вкладення своїх грошей в громадські підприємства. У рівновазі, передбаченою теорією, кожен учасник вносить нульовий внесок. У реальних експериментах результат, як правило, іншою: гравці вкладають певну суму в суспільне благо».
Людські якості
Ми не вважаємо гріхом нанести невелику шкоду природі або суспільству. «Від одного кинутого папірця світ не обвалиться» - так міркує перехожий, і міста заростають горами сміття.
Соціологи і психологи вже давно намагаються зрозуміти, як змусити людей бути більш альтруїстичними. Один з методів - залучення людини в процес, що дає йому відчуття гордості за принесене благо чи скорочення шкоди. Наприклад, на Літній школі «Українського репортера» студентам пропонують зробити внесок у розмірі від 150 до 600 гривень на добу - залежно від фінансових можливостей. Якщо якась частина учасників внесе мінімальний внесок, нічого страшного не станеться. Але якщо так зроблять всі, то Літня школа буде приречена на брак їжі та інші проблеми. Схоже, нас рятує відчуття причетності: «Це мій проект, я за нього теж відповідаю». Принаймні, останні кілька років середній внесок був удвічі більше мінімального.
З тієї ж серії поширення музики через Інтернет. Деякі групи пропонують завантажити свої твори безкоштовно, а потім, прослухавши, заплатити будь-яку суму. Якщо не заплатить ніхто, групі не на що буде записувати новий альбом.
Деякі економісти вважають, що саме за такими схемами майбутнє, принаймні в галузі розповсюдження музики, книг і кіно. Наприклад, професор Вищої школи економіки Олександр Долгін вводить поняття «постфактумні благодійні платежі». У його схемі економіка майбутнього зуміє перемогти халявщиків за рахунок публічності оцінки. Якщо я прочитав книгу або подивився фільм, я повинен виставити свою особисту оцінку - в якій мірі мені це сподобалося. І буде нелогічно, якщо я поставлю вищий бал і при цьому не пожертвую автору значну суму.
4. «Проблема кількості смертей»: чи можна з гуманізму вбити людину?
Правила
На залізниці ось-ось станеться аварія. Вагонетка, наповнена пасажирами, котиться в прірву. У вас є можливість її врятувати. Для цього треба своїми руками зіштовхнути на рейки вгодованого дорожнього робітника, який випадково опинився поруч. Людина загине. Але десятки життів буде врятовано. Ви готові?  Тоді, чому людина  обирає  смертельну у боротьбі за незалежність та інтереси суспільства?
Історія та застосування
Оригінальна формулювання цієї болісної дилеми була запропонована в 1967 році британським філософом Філіппом Фут в якості уявного експерименту з етики. За минулі роки з'явилося чимало модифікацій. Ви вбиваєте одного і рятуєте трьох. Ви вбиваєте дитину і зберігаєте життя десятьом. Є навіть пронизливий короткометражний фільм, в якому стрілочник повинен вибрати: розчавити власного сина конструкціями моста або допустити аварію потягу з сотнями пасажирів.
Найпоширеніше місце застосування цієї дилеми, звичайно, військові дії. Залишаючи взвод із прикривати відступ полку, командир відправляє на вірну смерть тридцять чоловік, але дає шанс тисячам вижити. Але ж така ситуація може трапитися і на реальній залізниці. Або під час пожежі. Або десь ще.
Не обов'язково має йтися про життя і смерть. Уявіть, що ви керівник відділу, якому потрібно звільнити одного співробітника, щоб зберегти весь колектив. Або ви ведете урок в школі, і вам доводиться накричати на одну дитину, щоб увесь інший клас міг спокійно займатися.
Людські якості
У цій грі дуже мало математики: десять - це більше, ніж один, це навіть першокласник знає. Зате психології з етикою в цій дилемі навалом. Заповідь «Не убий!» Вступає в протиріччя з цінністю збереження життя. До речі, у короткометражному фільмі про стрілочника головний герой все-таки жертвує своїм сином і потяг з нічого не підозрюють пасажирами спокійнісінько їде далі.
В експерименті, проведеному психологами з Університету Мічигану, випробуваним пропонувалася реалістична тривимірна модель з вагонеткою, шляхами і необхідністю погубити одного, щоб врятувати п'ятьох. Близько 90% учасників переводили стрілку і вбивали людину заради пасажирів вагонетки. Але це все-таки комп'ютерна реальність, а не справжнє життя.
5. «Яструби і голуби»: нападати або бігти
Правила
В одній популяції тварин співіснують дві групи з різними стратегіями боротьби за ресурси. Перші, «яструби», завжди налаштовані на конфлікт і при зустрічі з конкурентом йдуть до кінця. В результаті вони або виграють і привласнюють всі ресурси в околицях (+50 балів), або програють і отримують в бійці важкі каліцтва (-100 балів). «Голуби», навпаки, налаштовані миролюбно. Побачивши «яструба», вони відразу відступають (0 очок «голубу» і 50 очок «яструб»), а при зустрічі зі своїми родичами лише зображують готовність до сутички. Після тривалого обміну погрозами (-10 балів обом «голубам») ресурси дістаються більш щасливому «голубу» (+50 балів).
Є багато інших варіацій правил, але основні риси гри зберігаються незмінними: перемога приносить будь-якому птаху середню кількість очок, отримання каліцтв у «яструбів» прирівнюється до величезного штрафу, а ритуальні битви «голубів» теж вимагають деяких мінімальних витрат.
Мета гри гранично проста: заробити максимальну кількість очок, що б за ними не ховалося - їжа, гроші, самки або «представленість генів індивідуума в генофонді популяції», як висловлюється Річард Докінз у своїй книзі «Егоїстичний ген».
Історія та застосування
Правила гри були вперше опубліковані в журналі Nature в 1973 році. Автори роботи запропонували так формалізувати конфлікти тварин за ресурси, територію або сексуальних партнерів. Модель дозволяє по співвідношенню стратегій в популяції розрахувати кількість ресурсів, що витрачаються і одержуваних особинами при тому чи іншому варіанті взаємодій. Пташину метафору запозичили з геополітичного сленгу того часу («яструби» - за жорстке протистояння з противником, «голуби» - за розрядку і компроміси).
«Яструби і голуби» з'явилися як розвиток гри, в якій два водія несуться назустріч один одному. Переможеним вважався той, хто першим злякається лобового зіткнення і відійде в сторону.

Людські якості
- Ми спробували відійти від класичної теорії ігор, в якій набір можливих стратегій малий і жорстко заданий, - розповідає Михайло Бурцев, керівник лабораторії нейроінтеллекта і нейроморфних систем Курчатовського  інституту. У 2007 році він разом зі своїм керівником Петром Турчиним опублікував в Nature статтю, в якій описувалося, як стратегії «яструбів» і «голубів» виникають природним шляхом в процесі еволюції комп'ютерної моделі.
- Ми створили віртуальний світ, заселений агентами, які здійснюють примітивні дії, які могли бути скомбіновані в більш складні стратегії. Поведінка окремої агента управлялося власної нейронною мережею. Це дозволило нам відкрити такі стратегії, які в стандартній теорії ігор в голову не приходило досліджувати, - пояснює Михайло.

Так в процесі еволюції цього комп'ютерного світу в ньому з'явилися свої миролюбні «голуби», «яструби», які нападають на всіх чужаків, і навіть «шпаки», що збираються в зграї перед лицем небезпеки. Але найцікавіше - що у цих математичних агентів стали проявлятися піднесені людські почуття: турбота про родичів, самопожертва і альтруїзм.

пʼятницю, 6 лютого 2015 р.

Програмування операцій з квадратними масивами(матрицями) Pascal

Програмування  операцій з квадратними  масивами(матрицями)

Як було зазначено вище, одновимірні масиви застосовуються для зберігання послідовностей. Проте для багатьох структур даних зображення у вигляді послідовності є неприйнятним. Наприклад, результати матчів футбольного чемпіонату найзручніше подавати у вигляді квадратної таблиці. Для зберігання таких структур даних застосовують багатовимірні масиви, серед яких найбільш широко використовуються двовимірні масиви (матриці). У даному розділі розглядаються базові операції над елементами двовимірних масивів, а також техніка програмного розв'язування деяких матричних задач лінійної алгебри.

Базові операції обробки двовимірних масивів
Наведемо спочатку перелік базових операцій над матрицями та їх елементами. До таких операцій належать:
  • введення та виведення матриць;
  • створення нової матриці за заданим алгоритмом;
  • пошук елементів матриці за певним критерієм;
  • визначення, чи задовольняє матриця або окремі її елементи певній властивості;
  • виконання певних операцій над компонентами матриць (переставлення рядків і стовпців, множення матриць тощо).
Оголошення багатовимірних масивів. Доступ до елементів
Розглянемо прямокутну таблицю з m х n однотипних елементів, що містить m рядків та n стовпців. У математиці таку таблицю називають матрицею, а дані, що їх містить матриця, - елементами. У програмуванні матричні структури називаються двовимірними масивами.
Наведемо синтаксис оголошення змінної матричного типу в мові Pascal:
<ім'я матриці>:аrrау[<нижній індекс рядка>..<верхній індекс рядка>,<нижній індекс стовпця>..<верхній індекс стовпця>] of <тип елементів>;
У цьому оголошенні array, of — зарезервовані слова, <тип елементів> - будь-який тип, крім файлового, <нижній індекс рядка> і <верхній індекс рядка>— константи, що визначають межі діапазону допустимих значень індексу рядка, а <нижній індекс стовпця> та <верхній індекс стовпця> — константи, що визначають межі діапазону допустимих значень індексу стовпця. Масиви, що мають більш ніж два виміри, оголошуються в аналогічний спосіб.
Зазначимо, що, як і будь-який тип даних користувача, тип двовимірного масиву можна оголосити також в розділі type окремо від оголошення змінної матричного типу.
Наведемо приклади оголошень багатовимірних масивів. Нагадаємо, що обсяг сегмента пам'яті, де будуть зберігатися дані Pascal-програми, становить 64 Кбайт, і тому під час визначення розміру масиву необхідно враховувати можливість переповнення пам'яті.
const k=10; m=20; n=5;
type TMatrix=array[1..k,1..m] of integer;
var a:TMatrix;
  b:array[1..n,1..n] of real;
  c:array[1..4,1..3] of char;
  d:array[byte,1..2] of integer;
  mat:array[1..3,5..10,2..4] of integer;
Доступ до елементів матриці здійснюється операцією індексування [ ] за двома індексами, які визначають номер рядка та номер стовпця елемента. Синтаксис операції індексування є таким:
<ім'я масиву>[<номер рядка>,<номер стовпця>]
Зазначимо, що доступ до елементів масивів, які мають більш ніж два виміри, здійснюється також із застосуванням операції індексування. Але її операндами є більш ніж два індекси. Тепер дамо приклади індексування елементів оголошених вище масивів.
с[4,3]:='С';
mat[2,6,3]:=a[k,m]+d[0,2];
Перейдемо до розгляду форм зображення багатовимірних масивів. Як вже зазначалось, природною формою зображення двовимірного масиву вважається таблиця. Для прикладу на рис. 7.16 зображено масив, що може бути оголошений як
а:аrrау[1..4,1..4] of integer.
Рис. 7.16. Двовимірний масив розмірністю 4x4
Природне зображення багатовимірного масиву має суттєво відрізнятися від його зображення в оперативній пам'яті, адже оперативна пам'ять має лінійну структуру. За яким же принципом елементи матриці розташовуються в пам'яті комп'ютера? Спочатку у послідовних комірках записуються всі елементи першого рядка, потім у подальших послідовних комірках записуються елементи другого рядка і т. д., поки не буде вичерпано всі елементи. Розмір оперативної пам'яті визначається при оголошенні багатовимірного масиву і не змінюється під час роботи з ним.
На рис. 7.18 подано зображення в оперативній пам'яті двовимірного масиву
а:аrrау[1..4,1..4] of integer.
Рис. 7.18. Зображення матриці в оперативній пам'яті


Тепер розглянемо типові алгоритмічні схеми обробки елементів матриці з метою подальшого застосування цих схем до розв'язання матричних задач. Зробимо загальне зауваження: однотипну обробку всіх елементів деякої матриці найлегше здійснити шляхом її обходу за рядками або стовпцями. Тобто спочатку обробляються всі елементи першого рядка (стовпця), потім — всі елементи другого рядка (стовпця) і т. д. Найпростішим методом реалізації такого обходу є використання вкладених циклів for. Отже, перейдемо до розв'язання базових матричних задач.
Введення матриці є достатньо очевидною операцією:
var
  a:array[1..5,1..5] of integer;
  i,j:integer;
begin
  for i:=1 to 5 do
    for j:=1 to 5 do
      readln(a[i,j]);
end.
Стосовно виведення матриці слід зауважити, що у вікні результатів програми елементи матриці мають подаватись у вигляді таблиці. Тому переводити курсор на новий рядок слід лише після виведення всіх елементів поточного рядка:
var
  a:array[1..5,1..5] of integer;
  i,j:integer;
begin
  for i:=1 to 5 do
    begin
      for j:=1 to 5 do
        write(a[i,j],' ');
      writeln;
    end;
end.
Аналогічну структуру має код, що ініціалізує всі елементи матриці деякими значеннями:
var
  a:array[1..5,1..5] of integer;
  i,j:integer;
begin
  for i:=1 to 5 do
     for j:=1 to 5 do
       a[i,j]:=10;
end.
Одна з типових задач — пошук максимального або мінімального елемента матриці. Розв'язання цієї задачі нічим принципово не відрізняється від розв'язання аналогічної задачі для одновимірних масивів. У програмі ех7_13 здійснюється пошук значення та індексів максимального елемента матриці, яка ініціалізується випадковими числами. Максимальний елемент запам'ятовується у змінній max, індекс рядка, в якому розташований цей елемент, — у змінній іmах, а індекс стовпця — у змінній jmax.

Приклад 7.14
Program EX7_13;
var a:array[1..5, 1..5] of integer;
  i,j,imax,jmax:integer;
  max:integer;
begin
  randomize;
  for i:=1 to 5 do
    for
 j:=1 to 5 do
      a[i,j]:=random(20);
      max:=a[1,1];
  for i:=1 to 5 do    for j:=1 to 5 do      if max<a[i,j] then        begin
          max:=a[i,j];
          imax:=i;
          jmax:=j;
        end;
end.

Потреба у перестановці або обміні значеннями між двома елементами багатовимірного масиву виникає, насамперед, у задачах упорядкування. У деяких задачах переставляють рядки або стовпці.
Перестановку рядків або стовпців можна виконати лише шляхом послідовних перестановок відповідних елементів. Наведемо фрагмент коду, що демонструє перестановку першого та п'ятого стовпців матриці. Нагадаємо, що для обміну значеннями між двома елементами слід використовувати допоміжну змінну.
var a:array[1..5, 1..5] of integer;
  i,tmp:integer;
begin
  for i:=1 to 5 do    begin
      tmp:=a[i,1];
      a[i,1]:=a[i,5];
      a[i,5]:=tmp;
    end;
end.
Розглянемо такі операції, як вставка та видалення даних у багатовимірних масивах. Вставка та видалення окремих елементів матриці є, загалом, некоректними операціями, оскільки вони призводять до невизначеності щодо поведінки інших елементів: незрозуміло, слід зсувати елементи стовпця чи рядка, в яких відбувається вставка або видалення, чи здійснювати якийсь інший зсув. Тому найчастіше під час перетворення матриць операцію вставки або видалення поширюють на цілий рядок або стовпець. Але нагадаємо, що у будь-яких масивах будь-якої вимірності кількість елементів, яка була вказана під час оголошення, змінюватись не може. Тому вставка рядка або стовпця можлива тільки в межах оголошеної кількості рядків або стовпців. Видалення заданого рядка матриці демонструє програма ех7_14.

Приклад 7.15
Program EX7_14;
var a:array[1..5,1..5] of integer;
  i,j,k,n,m:integer;
begin
  writeln('enter number comb and column');
  readln(n,m);
  randomize;
  for i:=1 to n do
    for j:=1 to do
      a[i,j]:=random(20);
  writeln('enter number comb for delete');
  readln(k);
  for i:=k to n-1 do    for j:=1 to m do
      a[i,j]:=a[i+1,j];
  n:=n-1;
end.
Цикл видалення k-го рядка працює так: на місце k-го рядка записують рядок k + 1, на місце (k + 1)-гo рядка - рядок k + 2 і т. д., доки не буде вичерпано всі рядки. Оскільки обсяг пам'яті, що виділена під масив, під час його обробки не змінюється, то при видаленні будь-якого елемента масиву останній елемент буде дублюватися. Тому по завершенні циклу видалення слід зменшити на одиницю задану раніше кількість рядків.

Program MATRIX; {Найменування програми}
Uses CRT;
var i1, i2, i3: integer; {Лічильник рядків}
j1, j2, j3: integer; {Лічильник стовпців}
operation: integer; {Варіант розвитку програми}
det: real; {Визначник} k: integer; {Робоча змінна}
{Масиви (матриці), що використовуються в програмі}
MAS1, {Матриця А} MAS2, {Матриця В} MAS3: array [1 .. 10,1 .. 10] of real; {Матриця С}

BEGIN {Початок програми}
WriteLn ('Що Ви бажаєте робити з матрицями?');
{Вибір користувачем варіанту розвитку програми}
WriteLn ('Якщо Ви бажаєте знайти визначник матриці, натисніть 1');
WriteLn ('Якщо Ви бажаєте знайти зворотну матрицю, натисніть 2');
WriteLn ('Якщо Ви бажаєте транспонувати матрицю, натисніть 3');
WriteLn ('Якщо Ви бажаєте скласти матриці, натисніть 4');
WriteLn ('Якщо Ви бажаєте відняти матриці, натисніть 5');
WriteLn ('Якщо Ви бажаєте перемножити матриці, натисніть 6');
ReadLn (operation); {Занесення обраного варіанту в пам'ять}

WriteLn ('Введіть кількість рядків матриці, не більше 10');
ReadLn (m1);
WriteLn ('Введіть кількість стовпців початкової матриці, не більше 10');

ReadLn (n1);
If ((1> n1) or (n1> 10) or (1> m1) or (m1> 10)) {Умови помилки}
then begin  WriteLn ('ПОМИЛКА !!!');  end
else begin  WriteLn ('Введіть початкову матрицю'); {Введення вихідної матриці}
for i1: = 1 to m1 do
for j1: = 1 to n1 do Read (MAS1 [i1, j1]);  end;
for i1: = 1 to m1 do {Відповідь вихідної матриці}  begin
for j1: = 1 to n1 do  Write (MAS1 [i1, j1]);  WriteLn;  end;
Case operation of {Оператор вибору «operation»}
1: begin {Визначник}
if (m1 <> n1) then writeLn ('ПОМИЛКА !!!') {Умова помилки}  else
begin {Формула визначника}
det: = (MAS1 [1,1] * MAS1 [2,2] * MAS1 [3,3]+ MAS1 [2,1] * MAS1 [3,2] * MAS1 [1,3] + MAS1 [1,2] * MAS1 [2,3] * MAS1 [3,1])- (MAS1 [3,1] * MAS1 [2,2] * MAS1 [1,3]+ MAS1 [3,2] * MAS1 [2,3] * MAS1 [1,1]+ MAS1 [2,1] * MAS1 [1,2] * MAS1 [3,3]);
WriteLn ('Визначник матриці розміром 3х3, det =', det); {Висновок визначника}  end;  end;

2: begin {обернена матриця}
if (m1 <> n1) then WriteLn ('ПОМИЛКА !!!') {Умова помилки}  else begin  {Визначник}
det: = (MAS1 [1,1] * MAS1 [2,2] * MAS1 [3,3] + MAS1 [2,1] * MAS1 [3,2] * MAS1 [1,3]+ MAS1 [1,2] * MAS1 [2,3] * MAS1 [3,1])- (MAS1 [3,1] * MAS1 [2,2] * MAS1 [1,3]+ MAS1 [3,2] * MAS1 [2,3] * MAS1 [1,1]+ MAS1 [2,1] * MAS1 [1,2] * MAS1 [3,3]);
if det = 0 then WriteLn ('ПОМИЛКА !!!') {Умова помилки} else begin {Союзна матриця}
for i1: = 1 to m1 do
for j1: = 1 to n1 do MAS2 [i1, j1]: = MAS1 [j1, i1]; {Підсумкова формула}
for i1: = 1 to m1 do
for j1: = 1 to n1 do MAS3 [i1, j1]: = (1/det) * MAS2 [i1, j1];
WriteLn; WriteLn ('обернена матриця:');
for i1: = 1 to m1 do begin {Відповідь оберненої матриці}
for j1: = 1 to n1 do
Write (MAS3 [i1, j1]);   WriteLn;  end;    end;    end;  end;

3: begin {Транспонування матриці}
for i1: = 1 to m1 do
for j1: = 1 to n1 do MAS2 [i1, j1]: = MAS1 [j1, i1]; {Формула}
WriteLn ('Транспонована матриця:');
for i1: = 1 to m1 do begin {Відповідь транспонованої матриці}
for j1: = 1 to n1 do
Write (MAS2 [i1, j1]);  WriteLn;  end;  end;

4,5: begin {Додавання / віднімання матриць} {Введення другої матриці}
WriteLn ('Введіть кількість рядків другої матриці');  ReadLn (m2);
Writeln ('Введіть кількість стовпців другого матриці');  ReadLn (n2);
If (n2 <> n1) or (m2 <> m1)  then WriteLn ('OSHIBKA !!!') {Умова помилки}  else begin
WriteLn ('Введіть другу матрицю');
for i1: = 1 to m1 do
for j1: = 1 to n1 do
Read (MAS2 [i1, j1]);  end;
for i1: = 1 to m1 do {Вигляд другої матриці}  begin
for j1: = 1 to n1 do  Write (MAS2 [i1, j1]);  WriteLn; end;

if operation = 4 then k: = 1;
if operation = 5 then k: = -1;
for i1: = 1 to m1 do
for j1: = 1 to n1 do
MAS3 [i1, j1]: = MAS1 [i1, j1] + k * MAS2 [i1, j1]; {Підсумкова формула}
writeln ('Сума / різниця:');
for i1: = 1 to m1 do begin
for j1: = 1 to n1 do Write (MAS3 [i1, j1]);  WriteLn; end;    end;

6: begin {Множення матриць}  {Введення другого матриці}
WriteLn ('Введіть кількість рядків другий матриці');  ReadLn (m2);
Writeln ('Введіть кількість стовпців другого матриці');  ReadLn (n2);
If ((1> = m2) or (m2> = 10) or (1> = n2) or (n2> = 10) {Умова помилки}
or (n2 <> m1)) then WriteLn ('ПОМИЛКА !!!')  else begin
WriteLn ('Введіть другу матрицю');
for i2: = 1 to m2 do
for j2: = 1 to n2 do Read (MAS2 [i2, j2]);  end;
for i2: = 1 to m2 do begin {Вигляд другої матриці}
for j2: = 1 to n2 do  Write (MAS2 [i2, j2]);   WriteLn;  end;
m3: = m1; n3: = n2;
for i3: = 1 to m3 do
for j3: = 1 to n3 do begin   MAS3 [i3, j3]: = 0;
for i2: = 1 to m2 do   {Підсумкова формула}
MAS3 [i3, j3]: = MAS3 [i3, j3] + MAS1 [i3, i2] * MAS2 [i2, j3];
end;
begin {Вигляд добутку матриць}
writeln;
writeln ('Добуток двох матриць:');
for i3: = 1 to m1 do begin
for j3: = 1 to n2 do Write (MAS3 [i3, j3]);
WriteLn;
end; end;  end;  end; {End Case}
END. {Кінець програми}