Alibaba trebuie să descopere cifrul care deschide cufărul cu comoara cea mare. Cifrul este foarte greu de găsit. El a descoperit mai multe pietre, fiecare piatră având o altă culoare, pe fiecare piatră fiind scris un număr natural cu cel mult 4
cifre. Alibaba observă că numerele de pe fiecare piatră sunt distincte două câte două. Regula după care se formează cifrul este una foarte simplă, şi Alibaba a reuşit să o obţină destul de uşor: cifrul este format din alăturarea într-o anumită ordine a tuturor pietrelor. Ceea ce Alibaba mai ştie este că pe poziţia p
din cifru se găseşte cu siguranţă cifra k
.
Cerința
Scrieţi un program care determină numărul de variante de cifruri pe care va trebui să le încerce Alibaba. Numărul fiind foarte mare se va calcula modulo 46337
.
Date de intrare
Fișierul de ieșire cifru.out
va conține pe prima linie trei numere naturale n
, p
şi k
separate printr-un spaţiu, reprezentând numărul total de numere de pe pergament, poziţia p
şi respectiv cifra k
care se găseşte pe poziţia p
în cifru. Pe următoarele n
linii se găseşte câte unul din cele n
numere de pe pergament.
Date de ieșire
Pe prima linie a fişierului de ieşire cifru.out
se va scrie un număr natural reprezentând numărul de variante modulo 46337
de cifruri pe care va trebui să le încerce Alibaba.
Restricții și precizări
0 < n < 25
- Numerele de pe fiecare piatră sunt strict pozitive mai mici decât
10000
şi sunt distincte două câte două. 0 ≤ k ≤ 9
- Două cifruri diferă între ele prin ordinea de aşezare a pietrelor, chiar dacă numărul obţinut prin citirea numerelor de pe pietre este aceeaşi. De exemplu dacă există trei pietre având inscripţionate numerele
12
,3
şi respectiv123
, ele se pot lipi astfel:12-3-123
,123-12-3
, cele două cifruri considerându-se diferite, cifrele având culori diferite.
Exemplu
cifru.in
7 6 2 12 56 3 214 523 6 2
cifru.out
1548
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 Cifru:
#include <iostream>
#include <math.h>
#include <fstream>
using namespace std;
int sum, l;
long long sol;
long x[100],u[100],a[10],o[100],k,n,m;
int s[10];
int maxc;
long c[101][101];
int prime[100]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541};
long long perm(int k)
{ long long p=1;
for (int i=1;i<=k;i++)
p=(p*i) % 46337;
return p;
}
long long comb(int n,int k)
{
int x[100];
int m=0,j,i,d;
if (k==0 || k==n) return 1;
for (i=0;i<100;i++) x[i]=0;
for (i=n-k+1;i<=n;i++)
{
j=i;
d=0;
while (j!=1)
{
while (j%prime[d]==0)
{
x[d]++;
j=j/prime[d];
}
if (d>m)
m=d;
d++;
}
}
for (i=2;i<=k;i++)
{
j=i;
d=0;
while (j!=1)
{
while (j%prime[d]==0)
{
x[d]--;
j=j/prime[d];
}
d++;
}
}
long long p=1;
for (i=0;i<=m;i++)
for (j=1;j<=x[i];j++)
p=p*prime[i] % 46337;
return p;
}
void calc(int l)
{ int i;
long long v,p;
p=1;
for (i=1;i<=9;i++)
p=p*comb(a[i],s[i]);
v=p*perm(l) % 46337;
v=v*perm(n-l-1) % 46337;
sol=(sol+v) % 46337;
}
void back(int j,int nr)
{ int i;
for (i=0;i<=a[j];i++)
{ s[j]=i; sum=sum+s[j]*j;
l=l+i;
if (sum<=nr)
if (j<9 && sum<nr)
back(j+1,nr);
else
if (sum==nr)
calc(l);
sum=sum-s[j]*j;
l=l-i;
}
}
int main()
{
int v,i,t,p;
ifstream f("cifru.in");
for (i=1;i<=9;i++)
a[i]=0;
maxc=0;
f>>n>>p>>k;
for (i=0;i<n;i++)
{ f>>v; x[i]=0;
u[i]=0; o[i]=0;
while (v)
{ x[i]=x[i]*10+v%10;
u[i]++;
if (v%10==k)
o[i]=1;
v=v/10;
}
a[u[i]]++;
m=m+u[i];
}
f.close();
sol=0;
sum=0; l=0;
for (i=0;i<n;i++)
if (o[i]==1)
{ t=0; v=x[i]; a[u[i]]--;
while (v>0)
{ t++;
if (v%10==k)
back(1,p-t);
v=v/10;
}
a[u[i]]++;
if (u[i]>maxc) maxc=u[i];
}
ofstream g("cifru.out");
g<<sol;
g.close();
}
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 #722 Cifru
Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #722 Cifru 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!