Ćwiczenia do Modułu 1: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Daria (dyskusja | edycje)
Daria (dyskusja | edycje)
jedno na binsearch
Linia 37: Linia 37:
  '''program''' FlagaPolska2(N,A);
  '''program''' FlagaPolska2(N,A);
  '''const''' bialy = 0;
  '''const''' bialy = 0;
            czerwony = 1;
      czerwony = 1;
  '''var''' b,c : integer;
  '''var''' b,c : integer;
  '''begin'''
  '''begin'''
Linia 59: Linia 59:
  '''program''' FlagaPolska3(N,A);
  '''program''' FlagaPolska3(N,A);
  '''const''' bialy = 0;
  '''const''' bialy = 0;
            czerwony = 1;
      czerwony = 1;
  '''var''' b,c : integer;
  '''var''' b,c : integer;
  '''begin'''
  '''begin'''
Linia 92: Linia 92:
  '''program''' FlagaPolska4(N,A);
  '''program''' FlagaPolska4(N,A);
  '''const''' bialy = 0;
  '''const''' bialy = 0;
            czerwony = 1;
      czerwony = 1;
  '''var''' b,c : integer;
  '''var''' b,c : integer;
  '''begin'''
  '''begin'''
Linia 216: Linia 216:
  '''for''' i:=1 '''to''' N '''do''' '''begin'''
  '''for''' i:=1 '''to''' N '''do''' '''begin'''
   biez:=max(0,biez+A[i]);
   biez:=max(0,biez+A[i]);
   maks:=max(maks, biez)
   maks:=max(maks, biez);
  '''end''';
  '''end''';
  '''end'''.
  '''end'''.
Linia 321: Linia 321:
  '''program''' Podciag(N,A,M,B);
  '''program''' Podciag(N,A,M,B);
  '''var''' ia,ib: integer;
  '''var''' ia,ib: integer;
          istnieje: boolean;
    istnieje: boolean;
  '''begin'''
  '''begin'''
  '''if''' N > M then istnieje:=false
  '''if''' N > M then istnieje:=false
Linia 371: Linia 371:


== Zadanie 9 (Przesunięcie cykliczne) ==
== Zadanie 9 (Przesunięcie cykliczne) ==
Dana tablica A typu array[0..N-1] of integer, N > 1, i liczba naturalna k > 1. Napisz program realizujący przesunięcie cykliczne o k w prawo, czyli przesuwający zawartość pola A[i] na A[(i+k) mod N] dla każdego i<N.
Dana tablica A typu array[0..N-1] of integer, N > 1, i liczba naturalna k > 1. Napisz program realizujący przesunięcie cykliczne w prawo o k pól, czyli przesuwający zawartość pola A[i] na A[(i+k) mod N] dla każdego i < N.
===Możliwe rozwiązania zadania ===  
===Możliwe rozwiązania zadania ===  
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Linia 379: Linia 379:
  '''program''' Przesun1(N,A,k);
  '''program''' Przesun1(N,A,k);
  '''var''' i: integer;
  '''var''' i: integer;
          P: array[0..N-1] of integer;
    P: array[0..N-1] of integer;
  '''begin'''
  '''begin'''
  '''for'' i:=0 '''to''' N-1 '''do''' P[(i+k)mod N]:=A[i];
  '''for'' i:=0 '''to''' N-1 '''do''' P[(i+k)mod N]:=A[i];
Linia 402: Linia 402:
     A[nast]:=akt;
     A[nast]:=akt;
     akt:=pom;
     akt:=pom;
     nast:=(nast+k)mad N;
     nast:=(nast+k)mod N;
   '''end''';
   '''end''';
  '''end''';
  '''end''';
Linia 449: Linia 449:


== Zadanie 11 (Segment o zadanej sumie)  ==
== Zadanie 11 (Segment o zadanej sumie)  ==
Tablica A typu array[1..N] of integer zawiera tylko liczby dodatnie. Napisz program który dla danego W typu integer spradza czy w A istnieje segment o sumie W (czyli czy istnieją p, k takie, że W = \Sum_i \in [p ..k-1] A[i])
Tablica A typu array[1..N] of integer zawiera tylko liczby dodatnie. Napisz program który dla danego W typu integer sprawdza czy w A istnieje segment o sumie W (czyli czy istnieją p, k takie, że W = \Sum_i \in [p ..k-1] A[i])
=== Rozwiązanie 1 ===
=== Rozwiązanie 1 ===
<div class="mw-collapsible mw-made=collapsible mw-collapsed">   
<div class="mw-collapsible mw-made=collapsible mw-collapsed">   
Linia 455: Linia 455:
  '''program''' Segment_o_danej_sumie(N,A,W);
  '''program''' Segment_o_danej_sumie(N,A,W);
  '''var''' p,k,suma: integer;
  '''var''' p,k,suma: integer;
          istnieje: boolean;
    istnieje: boolean;
  '''begin'''
  '''begin'''
  '''if''' W < 0 '''then''' istnieje:=false  
  '''if''' W < 0 '''then''' istnieje:=false  
Linia 481: Linia 481:
===Możliwe rozwiązania zadania ===  
===Możliwe rozwiązania zadania ===  
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Najprościej sprawdzić dla każdego elementu po kolei czy występuje w tablicy ponad N/2 razy. Jest to rozwiązanie o kwadratowym koszcie czasowym.
Najprościej jest dla każdego elementu policzyć liczbę wystąpień w tablicy. Jest to oczywiście rozwiązanie o kwadratowym koszcie czasowym.
=== Rozwiązanie 1 ===  
=== Rozwiązanie 1 ===  
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
Linia 492: Linia 492:
   ile:=0;
   ile:=0;
   '''for j:=1 '''to''' N '''do''' if A[i]=A[j] '''then''' ile:=ile+1;
   '''for j:=1 '''to''' N '''do''' if A[i]=A[j] '''then''' ile:=ile+1;
   '''if''' (ile > (N+1) div 2) '''then''' zwyciezca:=i;
   '''if''' (ile > (N+1) div 2) '''then''' zwyciezca:=A[i];
  '''end''';
  '''end''';
  '''end'''.
  '''end'''.
Linia 499: Linia 499:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
To zadanie ma też (piękne) rozwiązanie liniowe. Składa się ono z dwu faz. W pierwszej wyznaczamy takie a, że jeśli jest zwycięzca, to jest nim a, w drugiej (banalnej) sprawdzamy czy a wygrał.
=== Rozwiązanie 2 ===  
=== Rozwiązanie 2 ===  
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
Linia 505: Linia 506:
  '''begin'''
  '''begin'''
  kand:=1;  
  kand:=1;  
  a:=A[kand];
  a:=A[1];
  ile := 1;
  ile := 1;
  i := 1;
  i := 1;
Linia 514: Linia 515:
     '''if''' ile > 0 '''then''' ile:=ile-1
     '''if''' ile > 0 '''then''' ile:=ile-1
     '''else''' '''begin'''
     '''else''' '''begin'''
      kand:=i;
       a:=T[i];
       a:=T[i];
       ile:=1;
       ile:=1;
Linia 523: Linia 523:
   '''if''' A[i]=a '''then''' ile:=ile+1;  
   '''if''' A[i]=a '''then''' ile:=ile+1;  
  '''if''' (ile > (N+1)div 2) '''then'''  
  '''if''' (ile > (N+1)div 2) '''then'''  
   zwyciezca:=kand
   zwyciezca:=a
  '''else''' zwyciezca:=0;
  '''else''' zwyciezca:=0;
  '''end'''.
  '''end'''.
Linia 532: Linia 532:
== Zadanie 13 (Arytmetyka liczb wielocyfrowych) ==
== Zadanie 13 (Arytmetyka liczb wielocyfrowych) ==
Liczby wielocyfrowe będą reprezentowane w tablicach typu liczba=array[0..N-1] of integer w taki sposób, że najmniej znacząca cyfra jest pod indeksem 0.
Liczby wielocyfrowe będą reprezentowane w tablicach typu liczba=array[0..N-1] of integer w taki sposób, że najmniej znacząca cyfra jest pod indeksem 0.
Rozpatrujemy liczby przy podstawie b>=1. Napisz procedury obliczające:
Rozpatrujemy liczby przy podstawie b &ge; 1. Napisz procedury obliczające:
* sumę liczb A i B do C. Jeśli wynik nie zmieści się w C to wartość C nie ma znaczenia. Zmienna przepełnienie wskazuje czy do niego doszło czy nie.
* sumę liczb A i B do C. Jeśli wynik nie zmieści się w C to wartość C nie ma znaczenia. Zmienna przepełnienie wskazuje czy do niego doszło czy nie.
* różnicę A i B do C. Jeśli wynik miałby byc liczbą ujemną to wartość C nie ma znaczenia. Zmienna ujemny wskazuje jaki jest znak wyniku.
* różnicę A i B do C. Jeśli wynik miałby byc liczbą ujemną to wartość C nie ma znaczenia. Zmienna ujemny wskazuje jaki jest znak wyniku.
* iloczyn A i B do C (C powinno być tablicą dwa razy dłuższą niż A i B, żeby móc pomieścić wynik).  
* iloczyn A i B do C (C powinno być tablicą dwa razy dłuższą niż A i B, żeby móc pomieścić wynik).  


procedure suma(A,B: liczba; var C:liczba; var przepelnienie: Boolean);
=== Rozwiązanie 1 ===
=== Rozwiązanie 1 ===
<div class="mw-collapsible mw-made=collapsible mw-collapsed">   
<div class="mw-collapsible mw-made=collapsible mw-collapsed">   
<div class="mw-collapsible-content" style="display:none">  
<div class="mw-collapsible-content" style="display:none">  
  '''const''' N=100;  
  '''const''' N=100;  
            b=10;  
    b=10;  
  '''type''' liczba = array[0..N-1] of integer;
  '''type''' liczba = array[0..N-1] of integer;
            dwa_liczba = array[0..2N-1] of integer;
    dwa_liczba = array[0..2N-1] of integer;


  '''procedure''' Suma(A,B:liczba, var C:liczba, var:przepelnienie:boolean);
  '''procedure''' Suma(A,B:liczba, var C:liczba, var:przepelnienie:boolean);
Linia 593: Linia 592:
</div>
</div>


== Zadanie INNE (Najdłuższy podciąg niemalejący) ==
Dana jest tablica A typu array[1..N] of integer, N > 1. Należy obliczyć długość najdłuższego podciągu niemalejącego w A.
=== Rozwiązanie 1 ===
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> 
Kluczowe jest użycie dodatkowej tablicy B rozmiaru N, w której pod indeksem i przechowuje się minimalną wartość kończącą podciąg niemalejący o długości i w dotychczas przejrzanej części tablicy A,  od 1 do k. Żeby uwzględnić A[k+1] należy w tablicy B odnależć miejsce na A[k+1] (najlepiej binarnie).
<div class="mw-collapsible-content" style="display:none">
'''program''' Podciag_niemalejący(N,A);
'''var''' : integer;
    B: array[1..N] of integer;
'''begin'''
ib:=1;
B[ib]:=A[1];
ia:=2;
'''while''' ia <= N '''do''' '''begin'''
  '''if''' A[ia] >= B[ib] '''then''' '''begin'''
    ib:=ib+1;   
    B[ib]:=A[ia];
  '''end'''
  '''else''' '''begin'''
    z:=ZnajdzPierwszyWiekszy(B,1,ib);
    B[z]:=A[ia];
  '''end''';
  ia:=ia+1;
'''end''';
'''end'''.
</div>
</div>





Wersja z 20:14, 10 lip 2006

Ta strona będzie zawierać podstawowe zadania na tablice.

Zadanie 1 (Flaga polska)

Tablica A typu array[1..N] of integer (N > 0) wypełniona zerami i jedynkami reprezentuje ciąg N urn w których znajdują się żetony białe (0) i czerwone (1). Należy podać algorytm działania automatu przestawiającego żetony w urnach tak, by najpierw były żetony białe, potem czerwone. Robot może wykonywać dwa rodzaje operacji:

  • Kol(i) - podaje kolor żetonu w i-tej urnie (1 ≤ i ≤ n)
  • Z(i,j) - zamienia żetony z i-tej i j-tej urny (1 ≤ i,j ≤ n)

Uwagi:

  1. Operacja Kol jest bardzo kosztowna, więc zależy nam na tym by kolor każdego żetonu był sprawdzany co najwyżej raz.
  2. Robot potrafi zapamiętać tylko kilka wartości z przedziału 0..N+1.
  3. Nie można założyć, że występuje choć jeden żeton w każdym z kolorów.

Możliwe rozwiązania zadania 1

Rozwiązanie 1

Rozwiązanie 1 optymalizuje liczbę sprawdzeń kolorów, ale może niepotrzebnie zamieniać czerwone z czerwonymi. Mozna tego uniknąć wprowadzając dodatkową pętlę po czerwonych od końca tablicy.

Rozwiązanie 2

W rozwiązaniu 2 są dwie zagnieżdżone pętle while. Trzeba zwrócić uwagę, że gdyby nie warunek b<c to w przypadku tablicy zawierającej same białe żetony doszłoby do wyjścia poza zakres (odwołanie do Kol(0)). Można uniknąć zagnieżdżonych while'i; trzeba jednak uważać aby nie sprawdzać kilka razy koloru tego samego żetonu.

Rozwiązanie 3

W rozwiązaniu 3 każdy żeton jest sprawdzany co najwyżej raz, a każda zamiana ustawia na dobrych miejscach 2 żetony (czyli zamian jest co najwyżej N div 2). Alternatywne rozwiązanie, unikające zagnieżdżonych pętli jest poniżej. Jednak dla tablicy złożonej z jednego żetonu czerwonego i potem samych białych będzie potrzeba N-1 zamian.

Rozwiązanie 4

Zadanie 2 (Flaga holenderska)

Dana jest tablica A typu array[1..N] of integer (N > 0). Należy tak poprzestawiać w niej elementy, żeby najpierw były elementy <0, potem =0, a na końcu >0.

Rozwiązanie 1

Zadanie 3 (Najdłuższe plateau)

Napisz program znajdujący w zadanej tablicy A typu array[1..N] of integer, N > 1, długość najdłuższego stałego segmentu (spójnego fragmentu tablicy).

Możliwe rozwiązania zadania 3

Rozwiązanie 1

Rozwiązanie 2

A co by było gdyby tablica A była posortowana ?

Zadanie 4 (Segment o maksymalnej sumie)

Napisz program znajdujący w zadanej tablicy A typu array[1..N] of integer, N > 1, maksymalną sumę segmentu (spójnego fragmentu tablicy). Przyjmujemy, że segment pusty ma sumę 0.

Możliwe rozwiązania zadania 4

Rozwiązanie trywialne, o kwadratowej złożoności:

Rozwiązanie 1

Rozwiązanie liniowe:

Rozwiązanie 1

Zadanie 5 (Część wspólna zbiorów)

Dane są dwie tablice A i B typu array[1..N] of integer, N > 1. Obie są posortowane rosnąco. Należy traktując A i B jako reprezentacje dwu zbiorów wypisać (operacją write) cześć wspólną tych zbiorów.

Rozwiązanie 1

Zadanie 6 (Suma zbiorów)

Dane są dwie tablice A i B typu array[1..N] of integer, N > 1. Obie są posortowane rosnąco. Należy traktując A i B jako reprezentacje dwu zbiorów wypisać (operacją write) sumę tych zbiorów.

Możliwe rozwiązania zadania 6

Rozwiązanie 1

Rozwiązanie 2

Zadanie 7 (Podciąg)

Dane są dwie tablice A typu array[1..N] of integer i B typu array[1..M] of integer, N, M > 1. Napisz program sprawdzający, czy A jest podciągiem B (tzn. czy istnieje funkcja f, rosnąca, z 1..N w 1..M, t. ze A[i]=B[f(i)]).

Rozwiązanie 1

Zadanie 8 (Odwracanie tablicy)

Dana tablica A typu array[0..N-1] of integer, N > 1. Napisz program odwracający kolejność elementów w A.

Rozwiązanie 1

Zadanie 9 (Przesunięcie cykliczne)

Dana tablica A typu array[0..N-1] of integer, N > 1, i liczba naturalna k > 1. Napisz program realizujący przesunięcie cykliczne w prawo o k pól, czyli przesuwający zawartość pola A[i] na A[(i+k) mod N] dla każdego i < N.

Możliwe rozwiązania zadania

Najprościej rozwiązać to zadanie używając dodatkowej pamięci rozmiaru N.

Rozwiązanie 1

Można też skorzystać z rozkladu na cykle elementów tablicy. Długość każdego takiego cyklu wynosi nww(N,k) a na dodatek pierwsze nwd(N,k) elementów należy do różnych cykli. Dodatkowym kosztem jest oczywiście obliczenie nww i nwd.

Rozwiązanie 2

Można też zauważyć, że przesunięcie cykliczne o k w prawo realizuje się porzez trzy odwrócenia pewnych segmentów w tablicy. Procedura Odwroc pochodzi z zadania 8.

Rozwiązanie 3


Zadanie 10 (Następna permutacja)

Tablica A typu array[1..N] of integer zawiera pewną permutację liczb 1.. N. Napisz program wpisujący do A następną leksykograficznie permutację. Zakładamy, że permutacja w A nie jest ostatnia leksykograficznie.

Rozwiązanie 1

Najpierw szukamy od tyłu pierwszego elementu, takiego że A[i] < A[i+1] (tu korzystamy z zalożenia że to nie ostatnia permutacja), potem szukamy na prawo od i najmniejszego większego od niego elementu k (uwaga: dużo wygodniej to robic od prawej strony!), potem zamieniamy te elementy i odwracamy kolejność elementów na prawo od i.

Zadanie 11 (Segment o zadanej sumie)

Tablica A typu array[1..N] of integer zawiera tylko liczby dodatnie. Napisz program który dla danego W typu integer sprawdza czy w A istnieje segment o sumie W (czyli czy istnieją p, k takie, że W = \Sum_i \in [p ..k-1] A[i])

Rozwiązanie 1

Zadanie 12 (Głosowanie większościowe)

Dana jest tablica A typu array[1..N] of integer, N > 1. Należy sprawdzić czy jest w niej element wystepujący więcej niż N/2 razy i jeśli tak wskazać go.

Możliwe rozwiązania zadania

Najprościej jest dla każdego elementu policzyć liczbę wystąpień w tablicy. Jest to oczywiście rozwiązanie o kwadratowym koszcie czasowym.

Rozwiązanie 1

To zadanie ma też (piękne) rozwiązanie liniowe. Składa się ono z dwu faz. W pierwszej wyznaczamy takie a, że jeśli jest zwycięzca, to jest nim a, w drugiej (banalnej) sprawdzamy czy a wygrał.

Rozwiązanie 2


Zadanie 13 (Arytmetyka liczb wielocyfrowych)

Liczby wielocyfrowe będą reprezentowane w tablicach typu liczba=array[0..N-1] of integer w taki sposób, że najmniej znacząca cyfra jest pod indeksem 0. Rozpatrujemy liczby przy podstawie b ≥ 1. Napisz procedury obliczające:

  • sumę liczb A i B do C. Jeśli wynik nie zmieści się w C to wartość C nie ma znaczenia. Zmienna przepełnienie wskazuje czy do niego doszło czy nie.
  • różnicę A i B do C. Jeśli wynik miałby byc liczbą ujemną to wartość C nie ma znaczenia. Zmienna ujemny wskazuje jaki jest znak wyniku.
  • iloczyn A i B do C (C powinno być tablicą dwa razy dłuższą niż A i B, żeby móc pomieścić wynik).

Rozwiązanie 1

Zadanie INNE (Najdłuższy podciąg niemalejący)

Dana jest tablica A typu array[1..N] of integer, N > 1. Należy obliczyć długość najdłuższego podciągu niemalejącego w A.

Rozwiązanie 1

Kluczowe jest użycie dodatkowej tablicy B rozmiaru N, w której pod indeksem i przechowuje się minimalną wartość kończącą podciąg niemalejący o długości i w dotychczas przejrzanej części tablicy A, od 1 do k. Żeby uwzględnić A[k+1] należy w tablicy B odnależć miejsce na A[k+1] (najlepiej binarnie).


Zadanie ()

Rozwiązanie 1

Zadanie ()

Możliwe rozwiązania zadania

Rozwiązanie 1