Tmp 6 2
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.