Tmp 6 2

From Algopedia
Jump to navigationJump to search

Tema Rezolvari

NrSufix

Fiind date două numere a şi b, îl numim pe a sufix al lui b dacă a este egal cu b sau dacă b se poate obţine din a prin alipirea la stânga a unor noi cifre. Exemplu: 12 este sufix al lui 12, iar 15 este sufix al lui 31415.

#include <stdio.h>

int main() {
    int n, x, m, p;
    FILE *fin = fopen( "nrsufix.in", "r" );
    FILE *fout = fopen( "nrsufix.out", "w" );
    fscanf( fin, "%d", &n );
    p = 1;
    while( p <= n )
      p = p * 10;
    m = -1;
    while ( fscanf(fin, "%d", &x) !=  EOF ) {     // citim valori pana la sfarsitul fisierului		 
        if( x % p == n )  			  // daca am taiat toate cifrele din cn, n e sufix al lui x
            m = x;				  // salvez nr x              
    }
    if ( m != -1 )				  // Daca am gasit un numar sufix
        fprintf( fout, "%d", m );		  // afisez nr salvat in m			
    else
        fprintf( fout, "nu exista" );

    fclose(fin);
    fclose(fout);
    return 0;
}
#include <stdio.h>

int main() {
    int n, cn, x, cx, m;
    FILE *fin = fopen( "nrsufix.in", "r" );
    FILE *fout = fopen( "nrsufix.out", "w" );
    fscanf( fin, "%d", &n );
    
    m = -1;
    while ( fscanf(fin, "%d", &x) !=  EOF ) {     // citim valori pana la sfarsitul fisierului
        cx = x;
        cn = n;
        while ( cn > 0 && cn % 10 == cx % 10 ) {  // cata vreme ultima cifra din cn este egala cu ultima cifra din x
            cn = cn / 10;						  // taiem ultima cifra din cn
            cx = cx / 10;                         // taiem ultima cifra din x
        }
        if ( cn == 0 )   			  // daca am taiat toate cifrele din cn, n e sufix al lui x
            m = x;				  // salvez nr x           						  
        
    }
    if ( m != -1 )				  // Daca am gasit un numar sufix
        fprintf( fout, "%d", m );		  // afisez nr salvat in m			
    else
        fprintf( fout, "nu exista" );

    fclose(fin);
    fclose(fout);
    return 0;
}

Jumatate

Se citește un număr natural n. Acest număr se “împarte” în alte două numere a și b, astfel: a este format din cifrele din prima jumătate a lui n, b este format din cifrele din a doua jumătate a lui n. Dacă n are număr impar de cifre, cifra din mijloc se ignoră. De exemplu, dacă n=9183792, atunci a=918, iar b=792. Să se determine valoarea absolută a diferenței dintre a și b.

#include <stdio.h>

int main() {
    int n, cn, nrcif, p, a, b, i;
    scanf("%d", &n);
    cn = n;
    // aflam cate cifre are n
    nrcif = 0;
    while ( cn > 0 ) {
        nrcif++;
        cn = cn / 10;
    }
    // mutam ultimele cifre in b
    b = 0; p = 1;
    for (i = 0; i < nrcif / 2; i++ ) {
        b = n % 10 * p + b;
        n /= 10;
        p = p * 10;
    }
    // daca am nr impar de cifre elimin cifra din mijloc
    if ( nrcif % 2 )
       n = n / 10;
    // in n a ramas cea de-a doua jumatate
    a = n;
    if ( a > b )
        printf("%d", a - b);
    else
        printf("%d", b - a);

    return 0;
}

Suma6

La ultima oră de matematică, Ionel a învățat despre numere speciale. Acestea sunt numere naturale cu număr impar de cifre care au prima cifră egală cu ultima. Ionel a primit ca temă să analizeze un șir format din numere având număr impar de cifre. El trebuie să determine suma cifrelor din mijloc, de la numerele speciale care se găsesc în șirul dat. Cerința Se citește numărul natural n și apoi se citesc n numere naturale având fiecare număr impar de cifre. Să se calculeze suma cifrelor din mijlocul numerelor speciale din șirul dat.

#include <stdio.h>

int main(){
    int n, i, x, p10, s;
    FILE *fin = fopen( "suma6.in", "r" );
    FILE *fout = fopen( "suma6.out", "w" );
    fscanf( fin, "%d", &n );
    s = 0;
    for( i = 0; i < n; i++ ){
      fscanf( fin, "%d", &x );
      // calculam puterea lui 10 mai mica sau eala cu x
      p10 = 100000000;
      while( p10 > x )
        p10 /= 10;
      
      if( x / p10 == x % 10 ){    // daca nr are prima si ultima cifra egale
        while( x > 10  ){         // scot din numar prima si ultima cifra pana cand raman cu o cifra sau niciuna
          x = ( x % p10 ) / 10;
          p10 /= 100;
        }
        s += x;					  // adun cifra din mijloc, pt numere cu nr par se aduna 0
      }
    }
    fprintf( fout, "%d", s );
    return 0;
}

Numere palindrom apropiate de n Studiu de caz 2

Enunt Varianta1

Se citeste un numar n. Sa se afiseze cel mai apropiat numar palindrom fata de n, diferit de n.
Ex1: n = 122 , afisam 121; nr 122 e cuprins intre 121 si 131, iar 121 este mai apropiat fata de 122
Ex2: n = 121 , afisam 111 131; 111, 131 sunt la aceeasi distanta fata de n
Ex3: n = 247 , afisam 242 252; 242, 252 sunt la aceeasi distanta fata de n

#include <iostream>
using namespace std;
int main(){
    int n, cn1, cn2, c1, c2, palin1, palin2, inv;
    cin >> n;               //citim n
    cn1 = n - 1;
    cn2 = n + 1;
    palin1 = palin2 = -1;                     // nu le-am gasit inca
    while ( palin1 == -1 && palin2 == -1 ){   // inca nu le-am gasit
      //verific daca cn1 e palindrom
      c1=cn1;
      inv = 0;
      while (c1 > 0){
        inv = inv * 10 + c1 % 10;
        c1 = c1 /10; //div
      }
      if (cn1 == inv ){
        palin1 = cn1;
      }
      //verific daca cn2 e palindrom
      c2 = cn2;
      inv = 0;
      while ( c2 > 0 ){
        inv = inv * 10 + c2 % 10;
        c2 = c2 /10; //div
      }
      if (cn2 == inv ){
        palin2 =cn2;
      }
      cn1 = cn1-1;
      cn2 = cn2+1;
    }
    if ( palin1 != -1 && palin2 != -1 )       // cand am gasit 2 la aceeasi distanta
      cout << palin1 << palin2;
    else if ( palin1 != -1 )                 // daca am gasit doar pe palin1
      cout << palin1;
    else
      cout < <palin2;

    return 0;
}

Enunt Varianta2

Se citeste un numar n. Sa se afiseze cel mai apropiat numar palindrom fata de n.
Ex1: n = 122 , afisam 121; nr 122 e cuprins intre 121 si 131, iar 121 este mai apropiat fata de 122
Ex2: n = 121 , afisam 121
Ex3: n = 247 , afisam 242 252; 242 si 252 sunt la aceeasi distanta fata de n

#include <iostream>
using namespace std;
int main(){
    int n, cn1, cn2, c1, c2, palin1, palin2, inv;
    cin>>n;               //citim n
    cn1=n;
    cn2=n;
    palin1 = palin2 = -1;                   //nu le-am gasit inca
    while (palin1 == -1 && palin2 == -1){   //inca nu le-am gasit
      //verific daca cn1 e palindrom
      c1=cn1;
      inv = 0;
      while (c1 > 0){
        inv = inv * 10 + c1 % 10;
        c1 = c1 /10; //div
      }
      if (cn1 == inv ){
        palin1 = cn1;
      }
      //verific daca cn2 e palindrom
      c2=cn2;
      inv = 0;
      while (c2 > 0){
        inv = inv * 10 + c2 % 10;
        c2 = c2 /10; //div
      }
      if (cn2 == inv ){
        palin2 =cn2;
      }
      cn1 = cn1-1;
      cn2 = cn2+1;
    }
    if ( palin1!=-1 && palin2!=-1 ){     // cand am gasit 2 la aceeasi distanta
      if( palin1 == palin2 )             // poate fi doar cazul in care n e palindrom 
        cout << palin1;
      else
        cout<<palin1<<" "<<palin2;       // afisez ambele numere
    }
      
    else if ( palin1!=-1 )               // daca am gasit doar pe palin1
      cout<<palin1;
    else
      cout<<palin2;

    return 0;
}

Parcurgerea numerelor din stanga si din dreapta unui numar n alternativ

Desigur ati observat ca algoritmii de mai sus contin codul de verificare a unui numar palindrom de 2 ori. Acest lucru poate fi evitat in doua moduri:

  • fie parcurgem numerele pe care trebuie sa le verificam serpuit, intai n+1, apoi n-1, apoi n+2 si n-2, etc...verificand doar un numar la un moment dat. Ne oprim cand am gasit un numar palindrom.
  • fie folosim functii ( subprograme ). Desi nu le-am studiat inca, unii dintre voi imi scriu deja rezolvari cu functii.

Haideti sa vedem o implementare a celor spuse pentru problema Benzinarii.

Varianta1

// Calculam urmatorul numar pe baza distantei de la precedentul numar pana la el

#include <fstream>
using namespace std;
int main(){
  int n, x, cp, pal, inv, semn, i;
  ifstream fin ( "benzinarii.in" );
  ofstream fout ("benzinarii.out" );
  fin >> n;
  x = n;
  pal = -1;                   // inca nu am gasit un palindrom
  semn = -1;                  // ne da directia numarului testat fata de n ( la st sau la dreapta)
  i = 0;                      // nr de valori pe care le verific
  do{
    i++;
    semn *= -1;               // ne spune daca e la stanga sau la dreapta lui n
    x = x + i * semn;         // +1,-2,+3,-4,+5,-6...fata de actualul nr
    // Verificam daca x e palindrom
    cp = x; inv = 0;
    while (cp > 0){
      inv = inv * 10 + cp % 10;
      cp = cp /10;
    }
    if ( x == inv )
      pal = x;
    //***************************
  }while ( pal == -1 );
  fout << ( i + 1 ) / 2 << " " << n + ( i + 1 ) / 2;
  fin.close();
  fout.close();
  return 0;
}


Varianta2

// Calculam urmatorul numar pe baza distantei de la n pana la el.

#include <fstream>
using namespace std;
int main(){
  int n, x, cp, pal, inv, semn, i;
  ifstream fin ( "benzinarii.in" );
  ofstream fout ("benzinarii.out" );
  fin >> n;

  pal = -1;                       // inca nu am gasit un palindrom
  semn = -1;                      // ne da directia numarului testat fata de n ( la st sau la dreapta)
  i = 0;                          // nr de valori pe care le verific
  do{
    i++;
    semn *= -1;                   // ne spune daca e la stanga sau la dreapta lui n
    x = n + ( i + 1 ) / 2 * semn; // +1,-1,+2,-2,+3,-3...
    // Verificam daca x e palindrom
    cp = x; inv = 0;
    while (cp > 0){
      inv = inv * 10 + cp % 10;
      cp = cp /10;
    }
    if ( x == inv )
      pal = x;
    //***************************
  }while ( pal == -1 );
  fout << ( i + 1 ) / 2 << " " << n + ( i + 1 ) / 2; // distanta si kilometrajul de pe bord
  fin.close();
  fout.close();
  return 0;
}

Varianta3

// Cu functii
#include <fstream>
using namespace std;
int palin ( int x ){
    int cp, inv;
    cp = x; inv = 0;
    while (cp > 0){
      inv = inv * 10 + cp % 10;
      cp = cp /10;
    }
    if ( x == inv )
      return x;
    return -1;
}
int main(){
  int n, x, pal,semn, i;
  ifstream fin ( "benzinarii.in" );
  ofstream fout ("benzinarii.out" );
  fin >> n;
  x = n;
  semn = -1;                  // ne da directia numarului testat fata de n ( la st sau la dreapta)
  i = 0;                      // nr de valori pe care le verific
  do{
    i++;
    semn *= -1;               // ne spune daca e la stanga sau la dreapta lui n
    x = x + i * semn;         // +1,-2,+3,-4,+5,-6...fata de actualul nr
    // Verificam daca x e palindrom
    pal = palin(x);
    //***************************
  }while ( pal == -1 );
  fout << ( i + 1 ) / 2 << " " << n + ( i + 1 ) / 2;
  fin.close();
  fout.close();
  return 0;
}

TEMA

Corectati-va rezolvarile problemelor discutate in clasa. Tema optionala.