Minta nagy ZH

Czirkos Zoltán · 2015.10.25

Minta nagy ZH, előző évek feladataiból összeollózva.

Minta nagy ZH, néhány előző évekből származó feladatból összeállítva. Ez minta. Egy-két tudnivaló a feladatsor felhasználásával kapcsolatban: lásd itt. Nem minden évben ugyanakkor volt az első NZH, nem minden évben pont ugyanaddig terjedt az első NZH anyaga.

1. Dátumok

A programunknak háromféle formátumban írt dátumot kell kezelnie: (a) 'éé.hh.nn, (b) éééé.hh.nn és (c) nn.hh.éééé formátumokat. Az (a)-nak aposztróf van az elején; továbbá ha a megadott kétjegyű év kisebb, mint 50, akkor a 2000-esekről beszélünk (pl. '12 = 2012), ha nagyobb vagy egyenlő, akkor az 1900-asokról (pl. '95 = 1995). A (b) és (c) formátumban biztosan négy számjeggyel van írva az év. Írj függvényt, amelynek első paramétere egy sztring, amely a fentiek közül valamelyik formában egy dátumot tartalmaz; a második paramétere pedig egy másik sztring, amelybe a dátumot „normalizálva”, éééé.hh.nn. formátumban kell írja! Írj rövid programrészt, amelyben kiírod normalizálva az alábbi dátumokat: '97.12.31, 29.10.2012, 2012.09.03.

Megoldás

#include <stdio.h>

void datum(char *in, char *out) {
    int ev, honap, nap;

    if (in[0]=='\'') {
        sscanf(in+1, "%d.%d.%d", &ev, &honap, &nap);
        if (ev<50)
            ev+=2000;
        else
            ev+=1900;
    } else {
        sscanf(in, "%d.%d.%d", &ev, &honap, &nap);
        if (ev<=31) { /* ha a nap lenne elöl, kicsi szám lesz */
            int tmp = ev;
            ev = nap;
            nap = tmp;
        }
    }
    sprintf(out, "%04d.%02d.%02d.", ev, honap, nap);
}

/* kódrész */
char res[20];
datum("'97.12.31", res); printf("%s\n", res);
datum("29.10.2012", res); printf("%s\n", res);
datum("2012.9.3", res); printf("%s\n", res);   /* ezt is eszi */

2. Prímszámok

Írj C programot, amely pozitív egész számokat kér be a felhasználótól! A számsorozat végét 0 jelzi. (A 0 után még érkezhet egyéb adat a bemeneten, de ezt a program már ne dolgozza fel!) Garantált, hogy a felhasználó maximum ezer darab számot ad meg a 0 előtt. A program írja ki az összes, a számok átlagánál kisebb beolvasott prímszámot a beolvasás sorrendjével ellentétes sorrendben! Az átlagszámításba a sorozat végét jelző 0 ne számítson bele!

Megoldás

#include <stdio.h>

int prim(unsigned szam) {
    unsigned oszto;
    for (oszto=2; oszto<szam; oszto++) {
        if (szam % oszto == 0)
            return 0;
    }
    return 1;
}

double atlag(unsigned *tomb, int meret) {
    double sum=0.0;
    int i;
    for (i=0; i<meret; i++)
        sum += tomb[i];
    return sum/meret;
}

int main(void) {
    unsigned tomb[1000], szam;
    int db, i;
    double atl;

    db=0;
    scanf("%u", &szam);
    while (szam!=0) {
        tomb[db++]=szam;
        scanf("%u", &szam);
    }
    atl=atlag(tomb,db);
    for (i=db-1; i>=0; i--)
        if (tomb[i]<atl && prim(tomb[i]))
            printf("%u\n",tomb[i]);
    return 0;
}

3. Könyvtár

Definiálj adattípust könyvtári könyvek adatainak tárolására! A tárolandó adatok: szerző (max. 30 karakter), cím (50), azonosító (egész szám), kiadás éve (egész), darabszám (egész).

Írj függvényt, amely paraméterként vesz át egy könyvtári könyvek adatait tartalmazó, fenti típusú elemekből álló tömböt, és rendezi azt szerző szerinti ABC sorrendbe!

Írj függvényt, amely paraméterként vesz át egy könyvtári könyvek adatait tartalmazó, fenti módon rendezett tömböt, és a szabványos kimenetre írja, hogy egy szerzőtől hány könyve van a könyvtárnak! Egy szerző neve csak egyszer szerepeljen a kiírt listában!

Megoldás

typedef struct {
   char szerzo[30+1];
   char cim[50+1];
   int azonosito, kiadas, db;
} konyv;

void rendez(konyv *t, int n) {
   int i, j, min;
   for (i = 0; i < n; i++) {
       min = i;
       for (j = i+1; j < n; j++)
           if (strcmp( t[j].szerzo, t[min].szerzo ) < 0)
               min = j;
       if (i != min) {
          konyv temp = t[min];
          t[min] = t[i];
          t[i] = temp;
       }
   }
}

void kiir(konyv *t, int n) {
   int i, db;
   for (i = db = 0; i < n; i++) {
       if (i == n - 1 || strcmp(t[i].szerzo,t[i+1].szerzo) != 0) {
           printf("%s: %d db\n",t[i].szerzo, t[i].db + db );
           db = 0;
       }
       else db += t[i].db;
   }
}

4. Palindrom

Írj C függvényt, amely megvizsgálja a paramétereként kapott sztringet, hogy az palindrom-e! A visszatérési értéke logikai igaz kell legyen, ha a sztring visszafelé olvasva, csak a benne szereplő számjegyeket és angol betűket figyelembe véve, valamint eltekintve azok kis- illetve nagybetűs voltától, ugyanaz, mint előrefelé; egyéb esetben pedig hamis.

Írj rövid főprogramot, amely beolvas egy legfeljebb 80 karakterből álló sort, és kiírja, hogy palindrom-e! Pl. palindrom: “Keresik a tavat a kis erek.”

Megoldás

#include <stdio.h>
#include <string.h>
#include <ctype.h>

/* két praktikus megoldás:
     (1) másolat a kihagyandók nélkül, és egyszerű összehasonlítás (mint a gyakon) 
     (2) szétválogatás tétele cserék nélkül (ügyesebb módszer; lásd lent) */
int palindrom(char const *str) {
    int eleje=0;
    int vege=strlen(str)-1;
    int pali=1;
    while (pali && eleje<vege) {
        while (eleje<vege && !isalnum(str[eleje]))
            eleje++;
        while (eleje<vege && !isalnum(str[vege]))
            vege--;
        if (eleje<vege)
            if (toupper(str[eleje]) != toupper(str[vege]))
                pali=0;
        eleje++;
        vege--;
    }
  
    return pali;
}

int main(void) {
    char sor[80+1];
    gets(sor);
    printf("%s\n", palindrom(sor) ? "Palindrom." : "Nem palindrom.");
    return 0;
}