Difference between revisions of "Clasa a VI-a lecția 38 - 6 iun 2019"

From Algopedia
Jump to: navigation, search
m (Cristian moved page Next to Clasa a VI-a lecția 38 - 6 iun 2019 without leaving a redirect)
 
Line 170: Line 170:
  
 
= Lecție =
 
= Lecție =
 +
<html5media height="720" width="1280">http://algopedia.ro/video/2018-2019/2019-06-06-clasa-6-lectie-info-38-720p.mp4</html5media>
 
== Jocul Tenis ==
 
== Jocul Tenis ==
 
Ca exercițiu de programare a funcțiilor avem o lecție specială astăzi. Încercați să scrieți funcțiile lipsă din jocul Tenis. Tenis este clasicul joc de tip "arcade", în care cei doi jucători mînuiesc două palete aflate în stînga și în dreapta ecranului, scopul fiind de a ține pe ecran o minge care se mișcă diagonal reflectîndu-se de margini sau de palete. Dacă unul din jucători scapă mingea celălalt jucător primește un punct și jocul se reia cu mingea de la centru.
 
Ca exercițiu de programare a funcțiilor avem o lecție specială astăzi. Încercați să scrieți funcțiile lipsă din jocul Tenis. Tenis este clasicul joc de tip "arcade", în care cei doi jucători mînuiesc două palete aflate în stînga și în dreapta ecranului, scopul fiind de a ține pe ecran o minge care se mișcă diagonal reflectîndu-se de margini sau de palete. Dacă unul din jucători scapă mingea celălalt jucător primește un punct și jocul se reia cu mingea de la centru.

Latest revision as of 05:41, 7 June 2019

Tema - rezolvări

Problema maya

Problema maya a fost dată la ONI 2019, clasa a 6a.

Iată o rezolvare posibilă:

#include <stdio.h>

int dlin[2][6] = { { 1, 1, 0, -1, 0, 1 },     // avans linie din coloana para
                   { 1, 0, -1, -1, -1, 0 } }; // avans linie din coloana impara
int dcol[6] = { 0, 1, 1, 0, -1, -1 };         // avans coloana
int nrap[26];             // numarul de aparitii al fiecarei litere
int lin[1000], col[1000]; // celulele de pornire

int main() {
  FILE *fin, *fout;
  int n, c, i, j, ch, max, dep, dir;

  fin = fopen( "maya.in", "r" );
  fscanf( fin, "%d%d ", &c, &n );
  max = 0;
  for ( i = 0; i < n; i++ ) {
    col[i] = fgetc( fin ) - 'A';   // citim coloana renumerotata de la 0 la 25
    fscanf( fin, "%d ", &lin[i] ); // citim linia, inclusiv spatiul de dupa
    nrap[col[i]]++;                // incrementam nr. de aparitii al coloanei
    if ( nrap[col[i]] > max )      // retinem numarul maxim de aparitii
      max = nrap[col[i]];
  }

  fout = fopen( "maya.out", "w" );
  if ( c == 1 ) { // cerinta unu, coloanele care apar de un numar maxim de ori
    for ( ch = 0; ch < 26; ch++ ) // afisam toate coloanele cu numar maxim de
      if ( nrap[ch] == max ) {    // aparitii
        fputc( ch + 'A', fout );
        fputc( ' ', fout );
      }
    fputc( '\n', fout );
  } else { // cerinta doi, simulare deplasari albine
    for ( i = 0; i < n; i++ )  {    // pentru fiecare pozitie initiala
      fscanf( fin, "%d ", &dep );   // citim numarul de deplasari
      for ( j = 0; j < dep; j++ ) { // pentru fiecare deplasare
        dir = fgetc( fin ) - '1';   // renumerotam directiile de la 0 la 5
        lin[i] += dlin[col[i] % 2][dir];         // avansam linia
        col[i] = (col[i] + dcol[dir] + 26) % 26; // avansam coloana
      }
      fputc( col[i] + 'A', fout );     // afisam coloana finala
      fprintf( fout, "%d\n", lin[i] ); // afisam linia finala
    }
  }
  fclose( fin );
  fclose( fout );

  return 0;
}

Problema optime

Problema optime a fost dată la ONI 2019, clasa a 6a.

Iată o rezolvare posibilă:

#include <stdio.h>

#define MAXK 200
#define MAXPRIM 1143893

char prim[MAXPRIM + 1]; // pentru ciurul lui Eratostene
int primcol[MAXK];      // numarul de numere prime pe coloana

int main() {
  FILE *fin, *fout;
  int c, k, x, d, i, j, suma, max;

  fin = fopen( "optime.in", "r" );
  fscanf( fin, "%d%d%d", &c, &k, &x ); // citim 3 desi uneori nu avem decit 2
  fclose( fin );

  // calculam ciurul lui Eratostene pina la MAXPRIM
  for ( i = 2; i * i <= MAXPRIM; i++ )
    if ( prim[i] == 0 )
      for ( d = i * i; d <= MAXPRIM; d += i )
        prim[d] = 1;

  suma = j = 0;
  i = 2;
  while ( j < 2 * k * k ) {
    if ( prim[i] == 0 && i % 100 > 9 ) { // daca face parte din tabel
      if ( prim[i % 100] == 0 ) // daca este prim
        primcol[j % k]++;       // adunam la nr prime ale coloanei
      else                      // altfel, daca nu e prim
        suma += i % 100;        // il adaugam la suma (cerinta 1)
      j++; // am mai gasit un numar din tabel
    }
    i++;   // avansam in ciur
  }
  
  fout = fopen( "optime.out", "w" );
  if ( c == 1 )
    fprintf( fout, "%d\n", suma );
  else { // cerinta doi, calculam coloanele cu nr maxim de nr prime
    // calculam suma primelor x coloane (ea va fi deocamdata si maximul)
    max = j = 0;
    for ( i = 0; i < x; i++ )
      max += primcol[i];

    // calculam toate sumele si le comparam cu maximul
    suma = max;
    for ( i = x; i < k; i++ ) {
      suma -= primcol[i - x]; // calculam suma curenta intre i-x+1 si i
      suma += primcol[i];
      if ( suma >= max ) {    // daca am gasit o suma mai mare
        max = suma;           // retinem acea suma in maxim
        j = i - x + 1;        // precum si pozitia ei de inceput (de la zero)
      }
    }
    fprintf( fout, "%d\n%d\n", j + 1, max );
  }
  fclose( fout );

  return 0;
}

Problema roata1

Problema roata1 a fost dată la ONI 2019, clasa a 6a.

Iată o rezolvare posibilă:

#include <stdio.h>

int poz[50000];

int main() {
  FILE *fin, *fout;
  int n, c, i;
  long long rot;

  fin = fopen( "roata1.in", "r" );
  fscanf( fin, "%d", &n );
  for ( i = 0; i < n; i++ ) {
    fscanf( fin, "%d", &c );
    poz[c - 1] = i; // retinem pozitia copilului c
  }
  fclose( fin );

  fout = fopen( "roata1.out", "w" );
  i = 0;   // pozitia care este jos la inceput
  rot = 0; // cite rotatii au fost facute anterior
  for ( c = 0; c < n; c++ ) { // pentru fiecare copil de dat jos din roata
    // r = (n - poz[c] + i) % n; // cate avansuri trebuie sa fac, minim
    // dorim sa aflam x astfel incit n * x + r > rot
    // adica x > (rot - r) / n
    // adica, pentru a avea un numar mai mare cu 1: x = (rot - r + n) / n
    // dar noi avem nevoie de numarul x * n + r
    // adica (n + rot - r) / n * n + r
    // adica (n + rot - r) - (n + rot - r) % n + r
    // adica n + rot - (n + rot - r) % n
    // n + rot - (n + rot - (n - poz[c] + i) % n) % n
    // n + rot - (n + rot + poz[c] - i) % n
    rot += n - (n + rot + poz[c] - i) % n;
    fprintf( fout, "%lld ", rot );
    i = poz[c];
  }
  fprintf( fout, "\n" );
  fclose( fout );

  return 0;
}

Rezolvări aici [1]

Lecție

Jocul Tenis

Ca exercițiu de programare a funcțiilor avem o lecție specială astăzi. Încercați să scrieți funcțiile lipsă din jocul Tenis. Tenis este clasicul joc de tip "arcade", în care cei doi jucători mînuiesc două palete aflate în stînga și în dreapta ecranului, scopul fiind de a ține pe ecran o minge care se mișcă diagonal reflectîndu-se de margini sau de palete. Dacă unul din jucători scapă mingea celălalt jucător primește un punct și jocul se reia cu mingea de la centru.

Instrucțiuni de lucru la joc:

  • Descărcați Tenis.zip.
  • Creați un proiect numit Tenis în CodeBlocks.
  • Copiați toate fișierele din tenis.zip acolo unde se află main.c.
  • Adăugați toate fișierele din tenis.zip la proiect ca surse C/C++.
  • Scoateți main.c din proiect.
  • Verificați că proiectul poate fi compilat (build)
  • Începeți lucrul la functii.c
  • Veți găsi mai multe instrucțiuni în legătură cu ceea ce aveți de făcut în fișierul functii.c

Cum jucăm:

  • Executați programul în mod obișnuit.
  • Jucătorul din stînga folosește tastele 'Q' și 'A'.
  • Jucătorul din dreapta folosește tastele 'O' și 'L'.
  • Jucătorul care acumulează 10 puncte cîștigă.
  • Pentru a opri jocul folosiți CTRL+C.

Pentru cei ce au terminat, idei de lucru mai departe:

  • Trasați marginile de sus și de jos ale terenului de tenis, pentru a intui mai bine momentul reflexiei mingei.
  • Experimentați cu diverse mărimi ale paletelor.
  • Avansat: încercați să schimbați culori.
  • Avansat: încercați să emiteți un sunet cînd mingea izbește o margine sau o paletă (la momentul reflexiei).

Temă

  • Terminați de codat jocul Tenis. Rezolvări aici [2]
  • Lucrați la Pah-Tum.