Un număr se numește palindrom dacă prima lui cifră este egală cu ultima, a doua cu penultima și așa mai departe. De exemplu numerele 1221
, 505
și 7
sunt palindromuri, în vreme ce 500
, 1410
și 2424
nu sunt palindromuri.
Similar, un număr se numește aproape palindrom dacă are aceleași perechi de cifre identice ca un palindrom, mai puțin o pereche în care cifrele diferă. De exemplu numerele 500
, 1411
, 2444
, 1220
, 53625
, 14
și 4014
sunt numere aproape palindromuri, în vreme ce 1221
, 1410
, 6
, 505
, 22
și 512125
nu sunt numere aproape palindromuri deoarece fie sunt palindromuri, fie au prea multe perechi de cifre diferite.
Mai definim palindromul asociat al unui număr x
ca fiind cel mai mic număr palindrom p
strict mai mare decât x
(p>x
). De exemplu palindromul asociat al lui 5442
este 5445
, palindromul asociat al lui 2445
este 2552
, al lui 545
este 555
, al lui 39995
este 40004
, al lui 500
este 505
, iar al lui 512125
este 512215
.
Cerințe
Scrieţi un program care citind un număr natural nenul n
și apoi un șir de n numere naturale determină:
1. câte dintre cele n
numere sunt palindrom
2. câte dintre cele n
numere sunt aproape palindrom
3. palindromurile asociate pentru cele n
numere citite.
Date de intrare
Fișierul de intrare palindrom2.in
conține pe prima linie un număr C
. Pentru toate testele, C
poate lua numai valorile 1
, 2
sau 3
. Pe a doua linie se află numărul n
, iar pe a treia linie cele n
numere naturale despărțite prin câte un spațiu.
Date de ieșire
Fișierul de ieșire palindrom2.out
:
- dacă
C=1
, va conține un singur număr natural reprezentând numărul de numere palindrom din șir - dacă
C=2
, va conține numărul de numere din șir care sunt aproape palindrom - dacă
C=3
, va conține numerele palindrom asociate celorn
numere din șir, separate prin câte un spațiu
Restricții și precizări
1 ≤ n ≤ 10 000
1 ≤
numerele din șir≤ 2 000 000 000
- Pentru rezolvarea corectă a primei cerinţe se acordă 20 de puncte, pentru rezolvarea corectă a celei de a doua cerințe se acordă 30 de puncte, iar pentru rezolvarea corectă a celei de a treia cerințe se acordă 50 de puncte.
Exemplul 1
palindrom2.in
1 7 1221 500 53635 505 7 4004 1410
palindrom2.out
5
Explicație
Explicație: Cele 5
numere palindrom sunt 1221
, 53635
, 505
, 7
și 4004
. (C
fiind 1
, se rezolvă doar prima cerință)
Exemplul 2
palindrom2.in
2 4 5442 2445 545 39995
palindrom2.out
3
Explicație
Explicație: Cele 3
numere aproape palindrom sunt 5442
, 2445
și 39995
. (C
fiind 2
, se rezolvă doar a doua cerință)
Exemplul 3
palindrom2.in
3 11 6 1411 2444 1221 505 1220 53625 14 4014 1410 22
palindrom2.out
7 1441 2552 1331 515 1221 53635 22 4114 1441 33
Explicație
Explicație: Palindromul asociat lui 6
este 7
, al lui 1411
este 1441
, al lui 2444
este 2552
etc. (C
fiind 3
, se rezolvă doar a treia cerință)
Cum e corect?
cout < "As la info";
cout << "As la info";
cout >> "As la info";
Felicitări! Poți mai mult?
Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.
Greșit, dar nu-i bai!
Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.
Rezolvare
Iată rezolvarea de 100 de puncte pentru problema Palindrom2:
/*
Cristian Francu 2016-02-01
Solutie optima la punctul (3)
- Testul de palindrom/aproape palindrom se face prin compararea cifrelor
simetrice, ceea ce nu produce depasiri in cazuri gen 1 999 999 999
- Palindromul asociat se genereaza in O(log x) (numarul de cifre ale lui x)
*/
#include <stdio.h>
int main() {
FILE *fin, *fout;
int c, n, i, x, cx, y, z, ndif, npali, napr, p10s, p10d;
fin = fopen( "palindrom2.in", "r" );
fout = fopen( "palindrom2.out", "w" );
fscanf( fin, "%d%d", &c, &n );
if ( c < 3 ) { // primele doua subpuncte se rezolva similar
npali = napr = 0;
for ( i = 0; i < n; i++ ) { // citim cele n numere
fscanf( fin, "%d", &x );
// punctele 1 si 2, este palindrom sau aproape palindrom?
// calculam cea mai mare putere a lui 10 care incape in x
p10s = 1000000000; // ea nu poate fi mai mare ca 1 miliard
while ( p10s > x )
p10s /= 10;
// calculam numarul de diferente intre cifrele lui x si y
ndif = 0;
cx = x;
while ( cx > 0 ) {
if ( cx / p10s != cx % 10 ) // comparam prima si ultima cifra
ndif++;
cx = cx % p10s / 10; // eliminam prima si ultima cifra din cx
p10s /= 100; // ajustam puterea lui 10
}
// in functie de ndif verificam daca e palindrom sau aproape palindrom
if ( ndif == 0 )
npali++;
else if ( ndif == 1 )
napr++;
}
fprintf( fout, "%d\n", c == 1 ? npali : napr );
} else { // punctul 3, palindromurile asociate (cel mai mic p > x)
for ( i = 0; i < n; i++ ) { // citim cele n numere
fscanf( fin, "%d", &x );
x++;
p10d = 1;
p10s = 1000000000; // cea mai mare putere plauzibila a lui 10
while ( p10s > x )
p10s /= 10;
// calculam rasturnatul primei jumatati a lui x in y
y = 0;
while ( p10s > p10d ) {
y = y + x / p10s % 10 * p10d; // prima cifra a lui cx la inceputul lui y
p10s /= 10;
p10d *= 10;
}
if ( y >= x % p10d ) // rasturnind prima jumate peste ultima obtinem
// un palindrom mai mare ca cel original?
x = x - x % p10d + y; // atunci acesta este palindromul cautat
else { // trebuie sa adunam 1 la prima jumate si sa o rasturnam
// adaugind-o la coada (y este acum inutil)
x = y = 1 + x / p10d; // prima jumate, inclusiv centrul la nr cif impar
if ( p10s == p10d ) // daca nr cf e impar taiem ultima cifra a lui y
y /= 10;
// rasturnam y in z
z = 0;
while ( y > 0 ) {
z = z * 10 + y % 10;
y /= 10;
}
x = x * p10d + z; // compunem prima jumatate cu prima jumatate intoarsa
}
fprintf( fout, "%d ", x );
}
fprintf( fout, "\n" );
}
fclose( fin );
fclose( fout );
return 0;
}
Atenție
Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa .
Rezolvarea problemei #1611 Palindrom2
Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1611 Palindrom2 de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.
Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!