Sunteți pe pagina 1din 6

Lecția 6 Divizibilitate- Optimizări

Cuprins
Problema #2324 prim002 ....................................................................................................................................................... 1
Problema #1409 – Numere11................................................................................................................................................. 2
Problema #2323 Prim001 ....................................................................................................................................................... 3
Problema #2363 Joc8 .............................................................................................................................................................. 4
Problema #3200 NeaDrăgulin ................................................................................................................................................. 5
Problema #2306 Numere22.................................................................................................................................................... 5

Problema #2324 prim002


Anul 2017 tocmai s-a încheiat, iar nostalgicii suferă în tăcere deoarece acesta era număr prim. Dorel, un personaj
întreprinzător, s-a gândit să afle pentru un număr natural n dat, care este cel mai mare divizor prim al acestuia.
Restrictii:
1 ≤ n ≤ 1014

Exemplu:

Intrare iesire
2018 1009

Divizorii lui 2018 sunt 1, 2, 1009, 2018, iar cel mai mare divizor prim este 1009.
Rezolvare 100p:

#include <iostream>
using namespace std;

int main()
{long long n, max = 0, d = 2;
cin >> n;
while(d * d <= n)
{ if(n % d == 0)
{while(n % d == 0)
n /= d;

if(d > max)


max = d;
}
d++;
}
if(n > 1)
max = n;
cout << max;
return 0;
}
Problema #1409 – Numere11
Se dau n numere naturale. Calculați suma obținută prin adunarea celui mai mare divizor prim al fiecărui număr
dat.
exemplu

9
7 30 2 17 14 10 9 3 13 => rezultat: 62

Rezolvare 100p:

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
int n,x;
long long sum=0;

cin>>n;
for(int i=1;i<=n; i++)
{
cin>>x;

///folosesc descompunerea in factori primi pentru a gasi cel mai


///mare factor prim din descompunere

int fp=2,fpmax=0;
while(x>1)
{
int p=0;
while(x%fp==0)///daca e factor impart si numar
{
p++;
x/=fp;
}
if(p>0) ///daca a fot factor il memorez ca fiind maxim
fpmax=fp;

fp++;

if(fp * fp > x)///s-a ajuns la x numar prim


fp = x;
}

sum=sum+fpmax; ///calculez suma


}
cout<<sum;
return 0;
}
Problema #2323 Prim001
Se dă un număr natural n. Să se afle numărul divizorilor naturali ai lui nn
Exemplu: dacă n=4 se va afișa 9 deoarece Numărul 44=256 are 9 divizori: 1, 2, 4, 8, 16, 32, 64, 128, 256.
Rezolvare 100p:
#include <iostream>
using namespace std;

long long n, m, d, p, exp[200], rez[200], k, i;

int main()
{
/// nrdiv=(e1+1)*(e2+1)*…(ek+1), unde e1..ek sunt puterile factorilor din
/// descompunerea in factori primi a lui n
cin >> n;

///descompunem n in factori primi si memoram puterile factorilor


d=2;
m=n;
while(m!=1)
{
p=0;
while(m%d==0)
{
m=m/d;
p++;
}
if(p>0)
{
k++; ///numar factorii
exp[k]=p;
}
d++;
}

/// nrdiv(n)=(e1+1)*(e2+1)*…(ek+1)
/// nrdiv(n^n)=(n*e1+1)*(n*e2+1)*…(n*ek+1)
/// Observatie:

/// cum aceste valori pot fi mari, efectuam operatiile % 59999


/// calculam puterile factorilor lui n^n

for (i=1; i<=k; ++i)


exp[i]=(n*exp[i]+1)%59999;

///determinam numarul de divizori dupa formula % 59999


m=1;
for (i=1; i<=k; ++i)
m=m*(exp[i])%59999;
cout << m;
}
Problema #2363 Joc8
Elena și Maria au primit cadou un joc. Dintr-o cutie ce conține mai multe numere, fiecare extrage pe rand câte un
număr și trebuie să descopere anumite condiții îndeplinite de aceste numere. Ele vor să determine câte numere
alternante au fost extrase. Un număr este alternant dacă are număr impar de cifre și dacă orice cifră a numărului, cu
excepția primei și a ultimei cifre se învecinează fie cu două cifre mai mari decât ea, fie cu două cifre mai mici decât ea.

Cunoscând numărul n de numere, precum şi cele n numere naturale extrase din cutie determinați câte dintre acestea
au fost alternante.

Exemplu:
joc8.in joc8.out
10 6
193 7 721 14263 28 279 9 1523142 769 15752

Numerele alternante sunt: 193, 7, 14263, 9, 1523142, 769.


Soluție 100p (Ispir Alexandru): - prelucrarea numerelor pe șiruri de caractere

#include <fstream>
#include <cstring>
using namespace std;
ifstream fin("joc8.in");
ofstream fout("joc8.out");
int main()
{
char s[15];
bool ok;
int n,nr=0;
fin>>n;
for(int i=1;i<=n;i++)
{
fin>>s;
if(strlen(s)%2==1)
{ ok=1;
if(strlen(s)==1)
nr++;
else
{
for(int j=1;s[j+1];j++)
if((s[j-1]<s[j] && s[j+1]<s[j])||(s[j-1]>s[j] && s[j+1]>s[j]))
continue;
else
{
ok=0;
break;
}
if(ok==1)
nr++;
}
}
}
fout<<nr;
return 0;
}
Problema #3200 NeaDrăgulin
Nea Drăgulin are un număr natural n pe care îl scrie de k ori, unul după altul. Aflați restul împărțirii numărului
astfel obținut la 72.
Exemplu:

Intrare iesire
51 3 63

Rezolvare 100p (Cherteș Andrei):


#include <iostream>
#include <cmath>
#define LL long long

using namespace std;

LL ridicareLog(int a,int b)
{
LL r=1;
while(b)
{
if(b%2==1)
r=r*a;
a=a*a;
b/=2;
}
return r;
}

int main()
{
LL n,k,p,cpy;
cin>>n>>k;
p=ridicareLog(10,log10(n)+1);
cpy=n;
while((k-1)%72>0)
{
k--;
n=((n % 72)*(p % 72)+cpy%72)%72;
}
cout<<n%72;
return 0;
}

Problema #2306 Numere22


Se dau două numere prime p, q și n numere naturale nenule. Determinați exponentul maxim e pentru care
numărul pe ⋅ qe divide produsul celor n numere date.
Restricții:
 1 ≤ n ≤ 1000
 cele n numere citite vor fi mai mici decât 1.000.000.000
Exemplu:

Intrare iesire
7 2 5 3
72 56 70 9 700

Rezolvare 100p (Barâlă Ștefana)


#include <iostream>
using namespace std;
void numere(int n, int v[], int p, int q)
{
int i, ep=0, eq=0;
for (i=1;i<=n; i++)
{
while (v[i]%p==0)
{
v[i]=v[i]/p;
ep++;
}

while (v[i]%q==0)
{
v[i]=v[i]/q;
eq++;
}
}
if (ep<eq)
cout<<ep;
else
cout<<eq;
}
int main()
{
int n, p, q, i, v[1001];
cin>>p>>q>>n;
for (i=1;i<=n;i++)
cin>>v[i];
numere(n, v, p, q);
return 0;
}

S-ar putea să vă placă și