Difference between revisions of "Clasa a V-a lecția 26 - 14 feb 2020"

From Algopedia
Jump to navigationJump to search
(Created page with "= Tema - rezolvări = == Problema cfdist == Problema [http://varena.ro/problema/cfdist cfdist] cere de fapt să se calculeze numărul de cifre distincte ale unui număr. El se...")
 
Line 75: Line 75:
 
     FILE *fin = fopen ( "plus.in", "r" );
 
     FILE *fin = fopen ( "plus.in", "r" );
 
     FILE *fout = fopen ( "plus.out", "w" );
 
     FILE *fout = fopen ( "plus.out", "w" );
     int  n, masca, invers;
+
     int  numar, masca, invers;
 
     fscanf( fin , "%d" , &numar );
 
     fscanf( fin , "%d" , &numar );
 
     masca = 0;  
 
     masca = 0;  

Revision as of 09:05, 14 February 2020

Tema - rezolvări

Problema cfdist

Problema cfdist cere de fapt să se calculeze numărul de cifre distincte ale unui număr. El se poate calcula ușor astfel: extragem în mod repetat ultima cifră c a numărului, avînd grijă să setăm vectorul de frecvență pe 1 la poziția c. În final parcurgem elementele vectorului de frecvență și numărăm cîte elemente 1 avem. Iată o soluție posibilă:

#include <stdio.h>

int v[10];

int main() {
  FILE *fin, *fout;
  int n, cf, nrcf;

  fin = fopen( "cfdist.in", "r" );
  fscanf( fin, "%d", &n );
  fclose( fin );

  while ( n > 0 ) {
    v[n % 10] = 1;
    n /= 10;
  }

  nrcf = 0;
  for ( cf = 0; cf < 10; cf++ )
    nrcf += v[cf];

  fout = fopen( "cfdist.out", "w" );
  fprintf( fout, "%d", nrcf );
  fclose( fout );

  return 0;
}

De remarcat că nu avem nevoie de numărul de apariții al cifrelor, de aceea stocăm unu, ori de cîte ori apare o cifră. Aceasta ne permite ca la final să calculăm suma elementelor vectorului de frecvență, fără a mai testa dacă valorile sînt zero.

Problema maxnr

Problema maxnr cere să se afişeze cel mai mare număr care se poate forma cu cifrele unui număr. Prima parte a rezolvării problemei este foarte similară cu problema anterioară (cfdist): vom construi vectorul de frecvență al cifrelor numărului, de data asta adunînd 1 pentru fiecate cifră. Apoi vom parcurge vectorul în sens invers, afișînd poziția curentă i de cîte ori ne spune elementul v[i]. Iată o rezolvare posibilă:

#include <stdio.h>

int v[10];

int main() {
  FILE *fin, *fout;
  int n, cf;

  fin = fopen( "maxnr.in", "r" );
  fscanf( fin, "%d", &n );
  fclose( fin );

  while ( n > 0 ) {
    cf = n % 10;
    v[cf]++;
    n = n / 10;
  }

  fout = fopen( "maxnr.out", "w" );
  for ( cf = 9; cf >= 0; cf-- )
    while ( v[cf] > 0 ) {
      fprintf( fout, "%d", cf );
      v[cf]--;
    }
  fclose( fout );

  return 0;
}

Problema plus

Problema plus poate părea la prima vedere o problema care se rezolvă cu vectori: fiecare cifră o așezăm în vectori și apoi facem operațiile aferente. Nu este o rezolvare rea, dar se poate rezolva foarte simplu prin manipularea cifrelor numărului. Scopul problemei era să vă determin să faceți diferența când trebuie să folosim sau nu vectori.

Iată o posibilă rezolvare:

#include <stdio.h>
int main()
{
    FILE *fin = fopen ( "plus.in", "r" );
    FILE *fout = fopen ( "plus.out", "w" );
    int  numar, masca, invers;
    fscanf( fin , "%d" , &numar );
    masca = 0; 
    inv = 0;

    // primul pas reprezintă răsturnarea numărului; 
    // în acest proces, avem grijă să adăugăm deja +1 
    while( numar ) { //adica cat timp există
        masca = masca * 10 + 1;
        invers = invers * 10 + numar % 10 ;
        numar = numar / 10;
    }

    fprintf( fout, "%d\n" , invers % 10 ); //afișăm prima cifră a numărului
    numar = masca + invers;
    invers = 0;

    // al doilea pas este să răsturnăm iarăși numărul;
    // astfel, îl aducem în forma corectă pentru afișare
    while( numar ) {
        invers = invers * 10 + numar % 10;
        numar = numar / 10;
    }

    fprintf( fout, "%d\n" , invers );
    fclose( fin );
    fclose ( fout );

    return 0;
}