![]() |
A 2002. januári informatika feladatok megoldása |
A közöltek csak megoldásvázlatok, esetleg csak végeredmények. A maximális pontszám eléréséhez általában ennél részletesebb megoldás szükséges. A részletes megoldásokat a beküldött dolgozatok alapján a KöMaL-ban folyamatosan közöljük.
I. 13. Egész számokat a 10-es mellett -10-es számrendszerben is felírhatunk, a következőképpen:
x=x0+(-10).x1+(-10)2.x2+...+(-10)n.xn
ahol 0\(\displaystyle le\)xi\(\displaystyle le\)9. Ebben a számrendszerben minden egész szám felírható előjelnélküli egész számként. Készítsünk programot (I13.pas, I13.c, ...), amely egy legfeljebb négyjegyű 10-es számrendszerbeli számot -10-es számrendszerbelivé vált, illetve fordítva: -10-esből 10-esbe?
Példák:
| 10-es | (-10)-es számrendszer | |
|---|---|---|
| 3 | 3 | |
| -6 | 14 | (=-10+4) |
| 34 | 174 | (=100-70+4) |
| -72 | 88 | (=-80+8) |
| 163 | 243 | (=200-40+3) |
| -527 | 1533 | (=-1000+500-30+3) |
| 1526 | 19686 | (=10000-9000+600-80+6) |
| 1994 | 18014 | (=10000-8000+0-10+4) |
(10 pont)
Forrásértelmezés:
Program JAN1;
Konstans
MaxN=100;
Típus
Itt tároljuk a számot, olyan formátumban, hogy tároljuk a hosszát, vagyis a számjegyek számát, illetve a számjegyeket.
Szám = Rekord( db : Egész; jegy : Tömb(0..MaxN:Egész))
Kiíratjuk, hogy milyen lehetőségek közül lehet választani.
Ki: Menü(Számrendszer konverzió, 1. Tízesből mínusz tízesbe, 2. Mínusz tízesből tízesbe)
Beolvassuk a választott menüpont számát, majd annak megfelelően elágazunk és elvégezzük a tízesből mínusztízesbe vagy a második pont választása esetén a mínusztízesből tízes számrendszerbe történő átváltást.
Be: c
Ha c='1'
akkor tizminusz
különben Ha c='2'
akkor minusztiz;
Program vége.
Eljárás tizminusz;
Változók
tizes, mtizes : Szám;
i, j: Egész;
Ki: A szám tízes számrendszerben?
Beolvassuk a tízes számrendszerben levő számot.
beolvas(tizes);
A mínusztízes számrendszerben levő számnak legalább annyi lesz a számjegyei száma, mint a tízes számrendszerben levőnek.
mtizes.db:=tizes.db;
Ciklus i:=0-tól MaxN-ig
Kinullázzuk a számjegyeket.
mtizes.jegy[i]:=0;
Ciklus vége;
Ciklus i:=mtizes.db-tól 0-ig -1-esével
A jegyek indexe az jelenti, hogy a számjegy, melyik helyiértékhez tartozik, vagyis az alap hányadik hatványát kell a számjeggyel megszorozni. Ezért a balról jobbra való feldolgozásnál a páros indexű helyen levő számjegy megegyezik a tízes és mínusz tízes számrendszerben. Viszont a páratlan index esetén komolyabb feldolgozásra van szükség. Paraméterként kapjuk meg a mínusz tízes számrendszerben felírt számot, átadjuk az indexet és a tízes számrendszerben felírt szám aktuális számjegyét.
Ha i mod 2=0
akkor mtizes.jegy[i]:=tizes.jegy[i]
különben negativ(mtizes,i,tizes.jegy[i]);
Elágazás vége
Ciklus vége;
Végül kiíratjuk a számot.
Ki: A szám mínusztízes számrendszerben:
kiir(mtizes);
Eljárás vége
Eljárás negativ(sz: Szám; i, mit: Egész;);
Ha a számjegy 0, akkor a mínusz tízes számrendszerben felír számjegy is az.
Ha mit=0
akkor sz.jegy[i]:=0
különben Ciklus
Különben a mínusz tízes számrend-szerben úgy tudjuk felírni a jegyet,hogy ezen a helyi értékű helyen szereplő számot kivonjuk tízből és az eggyel nagyobb helyen szereplő számjegyet növeljük eggyel.
sz.jegy[i]:=10-mit;
i:=i+1;
sz.jegy[i]:=sz.jegy[i]+1;
Ha ez tíz, akkor már nem tudjuk egy jeggyel leírni, ezért ez nulla lesz, az azutáni pedig eggyel kisebb, hiszen mínusz tízes számrend-szerbe írjuk fel a számot.
Ha sz.jegy[i]=10
Akkor sz.jegy[i]:=0;
i:=i+1;
sz.jegy[i]:=sz.jegy[i]-1
Elágazás vége;
Ha nullánál kisebb a következő számjegy, akkor úgy ismételjük ezta részt, mintha egyet kellene átírnunk ezen a helyiértéken.
Ha sz.jegy[i]<0
akkor mit:=1;
Elágazás vége;
Ezt kell ismételnünk, amíg nullánál kisebb a következő számjegy.
amíg sz.jegy[i]<0
Ciklus vége;
Ha közben nőtt a számjegyek száma, akkor azt elmentjük.
Ha i>sz.db
Akkor sz.db:=i;
Elágazás vége;
Elágazás vége;
Eljárás vége;
Eljárás minusztiz;
Változók
tizes, mtizes: Szám;
i,j: Egész;
Ki: A szám mínusztízes számrendszerben?
Beolvassuk a mínusz tízes számrendszerben felírt számot, amit feldolgozunk.
beolvas(mtizes);
A tízes számrendszerben felírt szám számjegyeinek száma kezdetben nulla.
tizes.db:=0;
Kinullázzuk a számjegyeket.
Ciklus i:= 0-tól MaxN-ig
tizes.jegy[i]:=0;
Ciklus vége
Az összes számjegyet fel kell dolgoznunk. A legnagyobb helyi értékűtől a legkisebbig.
Ciklus i:=mtizes.db-től 0-ig -1-esével
A páros és páratlan indexű helyen álló számjegyeket máshogy kell feldolgozni.
Ha i mod 2=0
akkor hozzaad(tizes,i,mtizes.jegy[i])
különben levon(tizes,i,mtizes.jegy[i]);
Elágazás vége;
Ciklus vége;
Ki: A szám tízes számrendszerben:;
Végül kiíratjuk a tízes számrendszerben felírt számot.
kiir(tizes);
Eljárás vége;
Eljárás hozzaad(sz: Szám; i, mit: Egész);
Változók
Ha az egyesek, százasok és így tovább a mínusz tíz páros hatványon szereplő helyi értékű jegyét vesszük, akkor ezzel a számjeggyel növelnünk kell a már ott szereplő számot. Van ott szám. Legalább a nulla, de előfordulhat, hogy a feldolgozás során már kapott értéket ez a jegy.
j: Egész;
Tehát hozzáadjuk.
sz.jegy[i]:=sz.jegy[i]+mit;
Majd megvizsgáljuk a számjegyeket, hiszen csak egyjegyű szerepelhet számjegyként. Ezért a kilencnél nagyobb számokbólkivonunk 9-et, majd a következő, egyel magasabb helyi értéken szereplő jegyhez hozzáadunk egyet. És megismételjük az ellenőrzést.
Ciklus amíg sz.jegy[i]>9
sz.jegy[i]:=sz.jegy[i]-10;
i:=i+1;
sz.jegy[i]:=sz.jegy[i]+1;
Ciklus vége;
Végül ha nőtt az értékes számjegyek száma, akkor azt elmentjük.
Ha i>sz.db
akkor sz.db:=i;
Elágazás vége;
Eljárás vége;
Eljárás levon(sz: Szám; i, mit: Egész);
Változók
Másik esetben - amikor a mínusz tízesek, mínusz ezresek, stb -, vagyis amikor páratlan indexű
jegyekkel foglalkozunk.
j: Egész;
Csökkentjük az aktuális számjegy értékét.
sz.jegy[i]:=sz.jegy[i]-mit;
Majd itt is ellenőrzést hajtunk végre, hiszen a számjegy nem lehet negatív. Vagyis hozzá kell adnunk tízet. A következő jegyet pedig eggyel csökkentjük.
Ciklus amíg sz.jegy[i]<0
sz.jegy[i]:=sz.jegy[i]+10;
i:=i+1;
sz.jegy[i]:=sz.jegy[i]-1;
Ciklus vége;
Eljárás vége;
Eljárás beolvas(sz: Szám);
Változók
s: szöveg;
i,j: Egész;
Beolvasunk egy számokból álló szöveget, melynek összes karakterét feldolgozzuk, vagyis mindegyik karaktert egy-egy számjegyé alakítunk. A legutolsó karakter lesz a számjegyek között a nulla indexű, hiszen ez felel meg az egyeseknek (10 a nulladikon).
Be: s;
sz.db:=Hossz(s)-1;
Ciklus i:=0-től sz.db-ig
val(s[sz.db-i+1],sz.jegy[i],j);
Ciklus vége;
Eljárás vége;
Eljárás kiir(sz: Szám);
Változók
i,j: Egész;
Fordított sorrendben íratjuk ki a számjegyeket, de csak azokat, melyek nem nullák.
i:=sz.db;
Ciklus amíg (i>0) ÉS (sz.jegy[i]=0)
i:=i-1;
Ciklus vége;
Az összes többi kiíratásra kerül.
Ciklus j:=i-től 0-ig -1-esével
Ki: sz.jegy[j];
Ciklus vége;
Eljárás vége;
Pascal program:
|
I. 14. Az arkhimédeszi spirális jellemzője, hogy a körbetekeredő spirál pontjai az előző körbelitől mindig azonos távolságra vannak. A logaritmikus spirális esetén pedig ezek a távolságok körbe-fordulásonként egy konstanssal szorzódnak.
Készítsünk programot (I14.pas, I14.c, ...), amely beolvassa a körbefordulások számát, majd ilyen arkhimédeszi és logaritmikus spirálist rajzol a képernyőre?
|
|
| Arkhimédeszi spirál | Logaritmikus spirál |
(10 pont)
Forrásértelmezés:
Program JAN2;
Változók
a, k, r, f, N: Valós;
x, y, xa, ya, xl, yl: Egész;
Eljárás Arkhimedeszi(r, f: Valós);
Az Arkhimédeszi spirál képlete: r=a.\(\displaystyle varphi\). Az f fokban szerepel, ezért radiánba számoljuk át.
r:=a*pi*f/180;
Eljárás vége;
Eljárás Logaritmikus(r, f: Valós);
A Logaritmikus spirál képlete:
. f itt is fok, amit ugyancsak átszámítunk
radiánba. k értékét számítjuk, míg a konstans 10.
r:=10*exp(k*pi*f/180);
Eljárás vége;
Eljárás Polar2Descartes(r, f: Valós; x, y: Egész);
A polárkoordinátákkal megadott pont távolság és szög értékeiből kiszámítjuk a derékszögű koordinátarendszerben levő x és y koordinátákat.
x:=Kerekít(r*cos(pi*f/180));
Ez egyszerű a szögfüggvényekkel. Egész értékekre kerekítünk, hiszen csak egész koordinátákat tudunk kirajzolni.
y:=Kerekít(r*sin(pi*f/180));
Eljárás vége;
Beolvassuk a körbefordulások számát.
Be: N;
Grafikus_felület_beállítása;
Feketével fogunk rajzolni.
SzínBeállítás(FEKETE);
Választó vonal a két spirális között a 640x320-as rajzlapon.
Vonal(320,0,320,320);
Az Arkhimédeszi spirálhoz ki kell számítanunk az egyes fordulatoknál levő konstans értékét. Ennyivel kell szorozni a szöget.
a:=150/N/2/pi;
A Logaritmikus spirál kitevőjében szereplő konstans kiszámítása, hogy kiférjen a képernyőre az ábra.
k:=ln(15)/N/2/pi;
Nulla szögnél kezdünk.
f:=0;
Kezdetben a középpontban állunk.
xa:=160;
Kezdetben a középpontban állunk.
ya:=160;
Kezdetben a középpontban állunk.
xl:=480;
Kezdetben a középpontban állunk.
yl:=160;
Ciklus amíg f<N*360
Kiszámítjuk az ehhez a szöghöz tartozó sugarat az Arkhimédeszi spirális esetén.
Arkhimedeszi(r,f);
Kiszámítjuk a polárkoordinátákhoz tartozó Descartes koordinátákat.
Polar2Descartes(r,f,x,y);
Eltoljuk a megfelelő középpontba a spirálist.
x:=160-x;
y:=160-y;
Vonalat rajzolunk az előző és az új pont között.
Vonal(xa,ya,x,y);
Lementjük az Arkhimédeszi spirális új pontjának koordinátái.
xa:=x;
ya:=y;
Kiszámítjuk az ehhez a szöghöz tartozó sugarat a Logaritmikus spirális esetén.
Logaritmikus(r,f);
Kiszámítjuk a polárkoordinátákhoz tartozó Descartes koordinátákat.
Polar2Descartes(r,f,x,y);
Eltoljuk a megfelelő középpontba a spirálist.
x:=480-x;
y:=160-y;
A legelsőt nem, de a többi vonalat kirajzoljuk az előző pont és az új pont között.
Ha f<>0
akkor Vonal(xl,yl,x,y);
Elágazás vége;
Lementjük a Logaritmikus spirális új pontjának koordinátáit is.
xl:=x;
yl:=y;
A szög növelése.
f:=f+1;
Ciklus vége;
Grafikus_felület_bezárása;
Program vége.
I. 15. Egy állatpopuláció tagjai maximum 10 évig élnek, a 10 korosztály létszámát tároljuk. Minden egyes korosztályhoz megadjuk, hogy egy egyede milyen eséllyel hal meg egy-egy évben (halálozási ráta), illetve átlagosan hány utódja születik (születési ráta).
Készítsünk táblázatot (I15.xls), amely tartalmazza a születési és halálozási rátákat, a kezdő létszámot, majd billentyű (billentyűkombináció) lenyomására számolja a következő évbeli korosztály-létszámokat és diagramot rajzol az egyes korosztályok összpopuláción belüli arányáról? Egy másik billentyű (billentyűkombináció) hatására pedig álljon vissza újra az 1. időpontba, a kezdőlétszámmal? Ha a létszámok számolásakor valós számok jönnének ki, azokat egészre kell kerekíteni?
Példa: (az 1. időegységben minden korosztályban 1000 állat volt)
|

(10 pont)
Megoldás:
A kezdeti állapotot legegyszerűbben úgy állíthatjuk vissza, ha egy különálló területen lementjük az adatokat, és a megfelelő billentyűkombinációra visszamásoljuk a kezdeti értékeket. Ezt legegyszerűbben egy Visual Basic makróval tehetjük meg.
Sub Ujra()
Erre a területre mentettük a kezdeti értékeket, amit most ki kell jelölnünk.
Range("D21:D32").Select
A vágólapra kell másolnunk.
Selection.Copy
Majd a helyére, jelen esetben a D6-os cellától kezdődően be kell másolni a Munkalapra.
Range("D6").Select
ActiveSheet.Paste
End Sub
A következő időpont állapotát pedig ugyancsak kiszámolhatjuk egy másik területre, például a mellette levő oszlopba, amit ismét csak át kell másolnunk, ha leütünk egy másik billentyűkombinációt. A Visual Basic makró itt is egyszerű:
Sub MASOL()
Ezen a területen található következő időpont korcsoportjainak egyedszámai, amit kijelölünk, vágólapra másolunk, majd a helyére, a szomszédos oszlopba, ugyanekkora területre másoljuk irányított beillesztéssel úgy, hogy csak az értékeket másoljuk, nem végzünk semmilyen műveletet, nem ugorjuk át az üreseket és nincs transzponálás.
Range("E6:E17").Select
Selection.Copy
Range("D6:D17").Select
Selection.PasteSpecial _
Paste:=xlValues, _
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
End Sub
Ezeket a makrókat meg is írhatjuk, de az Eszközök/Makró >/Új makró rögzítése... menüpont választásával ki is menthetjük.
[E7] =SZORZATÖSSZEG(E8:E16;$A7:$A15) a következő időpontban az első korcsoportba tartozó egyedek száma függ az összes többi korcsoporttól, hiszen bárhonnan születhet új egyed. Így itt egy összeget kell képeznünk. Mégpedig a megfelelő egyedszámot kell a születési rátával megszoroznunk és azok összegét vennünk. Persze csak az életben maradottaknak lehet utóduk.
[E10] =D9*(1-$B$9) a következő időpontban ezen korosztály egyedeinek a száma, hiszen a az előző időpontban levő egyedek közül annyi marad életben, amennyit az összes mínusz a halálozási rátával számolt egyedszámból tudunk megadni. Persze eltolás van közben, hiszen a következő időpontban ez a korcsoport már a következő lesz.
[E17] =SZUM(E7:E16) Az összes egyed száma nagyon egyszerű, hiszen ez az összegük.
A megoldás letölthető innen.


