Minta nagy NZH

Czirkos Zoltán · 2019.10.17.

Minta nagy ZH, néhány feladattal.

Minta nagy ZH. Tudnivalók a feladatsor felhasználásával kapcsolatban: lásd itt.

1. Minta nagy NZH

Ez csak minta. Nem minden évben ugyanakkor van a NZH, nem minden évben pont ugyanaddig terjedt a NZH anyaga; ezzel kapcsolatban lásd az aktuális évi előadásanyagot és tájékoztatást.

Tizennégy betű, tizennégy osztó

Az 1245 szám számjegyeit betűkkel, magyarul kiírva összesen 3+5+4+2=14 betűt használunk fel: „egy kettő négy öt”. Írj programot, amelyben megkeresed a legnagyobb négyjegyű számot, amely osztóinak száma 14 (beleértve saját magát és az 1-et is), és a számjegyeit leírva 14 betűt kell felhasználni! Írd ki, melyik ez a szám, vagy ha nincs ilyen, akkor azt!

Ne írj felesleges kódot! Használj fentről lefelé tervezést, írj a két részfeladathoz függvényeket (hány betű, osztók száma)! Emlékeztető: egy szám utolsó számjegyét eldobni tízzel való egész osztás segítségével tudod, míg magát az utolsó számjegyet a tízzel osztás maradéka adja meg.

ZH statisztika

Egy oktató statisztikát szeretne készíteni a megírt ZH-król. A ZH-ban három feladat van, ezek pontszáma nemnegatív egész szám, egyenként max. 10 pont, így az egész max. 30 pontos lehet.

Írj programot, mely a szabványos bemenetéről olvassa be soronként a ZH-k pontszámait. Az adatsort üres sor zárja. Ha hibás lenne a bemenet, jelenjen meg magyar nyelvű hibaüzenet!

Miután beolvasta a program az összes adatot, írja ki a szabványos kimenetre, hány 0 pontos, hány 1 pontos, … és hány 30 pontos megoldás lett. Ha adott pontszámú dolgozat nem született, az a sor ne jelenjen meg.

A programban NE tárold el a teljes bemenetet! Egy tömbbel (fix méretű listával) kell megoldani a feladatot.

Példa bemenet:

8 10 7
4 3 5
10 10 9
10 9 10

Példa kimenet:

12 pontos: 1 db
25 pontos: 1 db
29 pontos: 2 db
Megoldás
# Nem kérte a feladat, hogy külön függvényben legyen, de miért ne
def pontok(sor):         # ["10 8 9"]
    szamok = sor.split() # ["10", "8", "9"]
    return int(szamok[0]) + int(szamok[1]) + int(szamok[2])

def main():
    stat = [0] * 31         # [0, 0, 0, 0, ...... ]
    while True:
        sor = input()       # "10 8 9"
        if sor == "":
            break
        try:
            stat[pontok(sor)] += 1  # [0, 0, 0, 1, ......]
        except:
            print("Hibás bemenet:", sor)

    for pontszam in range(0, len(stat)):
        if stat[pontszam] != 0:
            print("{} pontos: {} db".format(pontszam, stat[pontszam]))

main()

Útiterv

Egy kamionsofőr autópályán vezet, 100 km/h-val haladva. A benzinkutak egymástól való távolságát előre ismeri a térképről. Minden másfél órányi vezetés után pihenőt kell tartania. Szeretne egy útitervet készíteni: előre eldönteni azt, hogy melyik benzinkúton kell majd pihennie. A szabály egyszerű: minden olyan benzinkútnál megáll, amelynél ha nem tartana pihenőt, a következő kúthoz már csak úgy érne el, ha túllépné a másfél órás egyfolytában vezetést.

Írj programot, amely soronként beolvassa az egyes benzinkutak közötti távolságot km-ben! Előbb megkapja a távolságok számát, magukat a távolságokat (valós számok, soronként egy darab). Végül pedig írja ki az útitervet. Például ha bemenetként a 45.3, 30.7, 64, 35, 72 számsort kapja (km-ek), akkor a kimenet az alábbi kell legyen:

45.3 km, 30.7 km, 64 km, szünet.
35 km, 72 km, vége.

(Az első három táv összesen 140 km, amihez 1,4 óra kell. Ha megtette volna a következő 35 km-t, ahhoz már 1,75 óra kellett volna, ezért jött a szünet.)

Megoldás
def main():
    sebesseg = 100  # km/h
    szunet = 1.5    # h

    n = int(input("n = "))
    tavok = []
    for _ in range(n):
        tavok.append(float(input("Táv (km): ")))

    megtett = 0     # km
    for tav in tavok:
        if (megtett + tav)/sebesseg > szunet:
            print('szünet.')
            megtett = 0
        print('{} km, '.format(tav), end='')
        megtett += tav

    print('vége.')

main()

A hiányos sorozat

Kapunk egy számsort, amiről tudjuk, hogy egy számtani sorozat elemei. Pontosan egy elem hiányzik belőle, de előre nem tudjuk, melyik. Adjuk meg a hiánytalan sorozatot, megjelölve a hiányzó elemet! Például:

Bemenet: 1 3 5 7 11
Kimenet: 1 3 5 7 *9* 11

Megjegyzés: nem az első elem hiányzik, és nem is az utolsó (mert akkor olyan lenne, mintha nem hiányozna egyik sem). És azt is lehet tudni, hogy legalább három elem van.

Megoldás

Érdemes előbb a sorozat differenciáját (növekményét) meghatározni. Arra jöhetünk rá, hogy ehhez elég a számsor első három elemét megvizsgálni. Ugyanis ha ilyesmit látunk:

1 3 5

Akkor az első három elem rendben van, mert közöttük d = 2 a különbség mindkét helyen; nem hiányzik elem sem az 1 és a 3 közül, sem a 3 és az 5 közül. Ha ezt látnánk:

1 3 7

Akkor tudnánk, hogy a 3 és a 7 közül tűnt el a szám, mivel ott nagyobb a különbség (d = 4), mint az első két elem között (d = 2). A sorozat differenciája pedig 2 kell legyen. Ha pedig ezt kapjuk:

1 5 7

Akkor az első pár között van a hiány, mert ott d = 4, a második párnál viszont csak d = 2. Összefoglalva: a sorozat differenciája az első két elempár között látott különbségek közül a kisebbik.

Ha megvan a differencia, akkor csak ki kell írni a sorozat elemeit, és közben figyelni, mennyi kellene legyen a kiírt elem. Ha nem annyi, akkor megvan a hiány. Mindig annyi kellene legyen, mint az előző elem plusz a differencia. A kiírásnál megtehetjük azt is, hogy kiírjuk a sorozat elején lévő elemet külön (azt még nincs mihez hasonlítani). De tekinthetjük úgy is, mintha a sorozat első eleme előtt sorozat[0] - d lett volna.

sor = []
while True:
    try:
        sor.append(int(input()))
    except:
        break

diff = min(sor[1]-sor[0], sor[2]-sor[1])

elozo = sor[0] - diff
for x in sor:
    if elozo + diff != x:
        print("*{}*".format(elozo + diff), end=" ")
    print(x, end=" ")
    elozo = x

Érdemes elgondolkozni azon, hogy megoldható-e ez a feladat lista nélkül. Emlékezzünk vissza: ha sorban kell feldolgozni az elemeket, és nem kell sem előre, sem hátra látni a sorozatban, akkor nincs szükség az adatok tárolására. (Spoiler alert: megoldható lista nélkül.) Kegyelemdöfésként pedig jegyezzük meg, hogy valójában a hiányos sorozat differenciája még ennél egyszerűbben is meghatározható: (sor[-1] - sor[0]) / len(sor), vagyis az utolsó és az első elem különbsége, osztva a sorozat hosszával.

2. Feladatok a próba NZH-ról

Ezt a próba ZH-t a Seniorgárda szervezte.

Boldog számok

Írj programot, amely kiírja két pozitív egész szám közé eső összes boldog számot! Az alsó és a felső határt a felhasználó adhassa meg!

Boldog szám az, amelyre igaz, hogy ha kiszámítjuk számjegyeinek négyzetösszegét, majd ezt a kapott számmal addig ismételjük, amíg egyjegyű számot nem kapunk, akkor az eredmény 1 lesz. Például boldog szám a 23, mert 22 + 32 = 13, 12 + 32 = 10 és végül 12 + 02 = 1.

Nagyon tökéletes számok

Nagyon tökéletes számoknak nevezzük azokat a számokat, amelyek osztói összegének osztóit összegezve az eredeti szám kétszeresét kapjuk. Az első ilyen szám a 2, mert osztóösszege 1+2=3, aminek osztóösszege 1+3=4, ami az eredeti 2 duplája.

Melyik az 5-ödik ilyen? Írj programot, amelyik kiszámítja és kiírja!

Átszállások

Buszjáratok megállóinak neveit tároljuk listákban. A programod feladata, hogy beolvassa a buszjáratok adatait, és megmondja két adott járatról, hogy át lehet-e szállni egyikről a másikra, vagy nem; és ha igen, hol.

Írj programot, amely a szabványos bemenetről beolvassa két járat megállóit, üres sorig, majd megvizsgálja, hogy van-e közös megállója, és ha van, kiírja azt.