Przykładowe (być może nie jedyne wcale!) właściwe rozwiązania zadań z omówieniami

 

UWAGA: użycie typu Real w zadaniach A i C może prowadzić do błędów zaokrągleń!!! (Komputer zapisuje przecież poprawnie tylko wielokrotności potęg dwójki, inne liczby muszą zostać jakoś przybliżone!...)

 

Zad. A. Program wypisujący na ekranie reszty z dzielenia przez 7 kolejnych naturalnych potęg czwórki nieprzekraczających miliona.

Var potega:LongInt; {Moze byc tez Real, ale wtedy jest klopot z wyswietlaniem, no i po co, skoro

te wartosci sa calkowite, a patrz uwaga wyżej!}

Begin

  potega:=1; {Można tez zaczac od 4, jeśli uznac, ze naturalne potegi to te,

które maja wykladniki calkowite dodatnie.}

  While potega<=1000000 do {Może być tez ostra nierownosc, bo akurat tu wiemy, ze dokladnie 1000000 nigdy nie będzie.}

    Begin

      potega:=potega*4;

{*}   WriteLn(potega mod 7); {srednik zbedny}

    End; {srednik zbedny}

End.

Tak napisany program NIE JEST poprawny z tego samego powodu, co nasze pierwsze podejście do wypisywania liczb pierwszych na ostatnich zajęciach! - Wypisze również resztę z dz. p. 7 najmniejszej potęgi przekraczającej milion! (Poza tym nie drukuje tej reszty dla początkowej wartości potęgi). Linię {*} można więc opatrzyć warunkiem (i ew. dodatkowo rozpatrzyć wartość początkową przed pętlą) albo po prostu przenieść przed zwiększanie potęgi! J

 

Zad. B.

W Pascalu zapisujemy definicję:

Function g(a:Real; b:LongInt):xxx;

Begin

  If b=0 then g:=0

    else g:=a+g(a,b-1)

End;

a) Co powinniśmy wpisać w miejsce „xxx”? Dlaczego?

„Real”, bo wartość g może (przy b>0) być sumą, której jeden ze składników (a) jest typu Real. Uzasadnienie „bo a jest typu Real” jest niewystarczające! Stała pi też jest typu Real, i co z tego?! Co więcej – łatwo wyobrazić sobie funkcję o argumencie typu Real, a wartościach całkowitych (jak choćby signum czy entier)!

b) Pokaż, jak Pascal obliczy g(11,3). Ile wynosi ta wartość?

g(11,3) = 11+g(11,2) = 11+(11+g(11,1)) = 11+(11+(11+g(11,0))) = 11+(11+(11+0)) = 33

 

Zad. C. Program znajdujący sumę wszystkich podzielnych przez 3 liczb czterocyfrowych, których przedostatnia cyfra jest nieparzysta.

Var c1,c2,c3,c4,suma:LongInt; {Kolejne cyfry kolejnych liczb 4-cyfrowych i szukana suma.}

Begin

  suma:=0;

  For c1:=1 to 9 do

    For c2:=0 to 9 do

      For c3:=0 to 9 do  {Tu mozna podarowac sobie 0 - dlaczego?)

        For c4:=0 to 9 do

          If c3 mod 2 =1 then

            If (c1+c2+c3+c4) mod 3 =0 {Nawias konieczny! - dlaczego?} then

               suma:=suma+((c1*10+c2)*10+c3)*10+c4; {Przyklad zastosowania schematu Hornera

- oczywiscie mozna tez "normalnie".}

  WriteLn(suma); {srednik zbedny}

End.

Powyższy program niepotrzebnie wchodzi w najbardziej wewn. pętlę, gdy przedost cyfra jest parzysta – nietrudno można go ulepszyć – jak?

Można też dla danego układu (c1,c2,c3,c4) wygenerować sobie odpowiednią 4-cyfrową liczbę (1000c1+100c2+10c3+c4) i bezpośrednio sprawdzać jej podzielność przez 3 oraz ew. dodać. Wówczas jednak potrzebne będą begin i end - czemu?

A można też całkiem zupełnie diametralnie (?) inaczej (ciekawe, czy wyjdzie to samo...):

Var liczba,suma:LongInt;

Begin

  suma:=0;

  For liczba:=1000 to 9999 do {Zaczac petle mozna (ale czy warto?) nawet od 1011 – dlaczego?}

    If liczba mod 3 =0 then

      If (liczba div 10) mod 2 =1 {O co tu chodzi??

  A nawias dla pewnosci – nie wiem, czy jest potrzebny, ale sadze, ze absolutnie nie warto tego sprawdzac!} then

        suma:=suma+liczba;

  WriteLn(suma); {srednik zbedny}

End.

 

Zad. D. Pascalowa rekurencyjna definicja ciągu arytmetycznego o pierwszym wyrazie 7 i różnicy -2.

Ciąg jest formalnie definiowany jako funkcja (o dziedzinie...?). Rekurencja polega na odwołaniu się funkcji (czy też procedury) do samej siebie. Ciąg arytmetyczny powstaje przez dodawanie do kolejnych wyrazów pewnej stałej (różnicy). Będzie więc np. po prostu:

Function ca(n:LongInt):LongInt; {Typem wyniku moze byc Real, ale po co?!}

Begin

  If n=1 then ca:=7 {Niektore podreczniki wola numerowac wyrazy od 0, ale my umawialismy sie zaczynac od 1.}

    else ca:=ca(n-1)-2

End;

 

Życzę miłej nauki i wysokich wyników na egzaminie!

M.Ś.