Cod sursa(job #869762)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 2 februarie 2013 10:47:25
Problema Pascal Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.35 kb
#include <fstream>

using namespace std;

//In acesti vectori se retine cati factori de 2,3 sau 5 sunt in descompunerea numarului i, indice al vectorului
unsigned short int fact2[5000001];
unsigned short int fact3[5000001];
unsigned short int fact5[5000001];

int main()
{
	//Deschiderea fisierelor de intrare si iesire
	ifstream fin("pascal.in");
	ofstream fout("pascal.out");
	
	//d si r din enuntul problemei
	int d,r;
	
	//i - contor
	int i;
	
	//Citim datele problemei
	fin>>r;
	fin>>d;
	
	//Construim vectorii prin programare dinamica
	for(i=2;i<=r;i++)
	{
		//Numai numerele divizibile cu 2,3 sau 5 trebuie calculate, restul sunt 0
		if(i%2==0)
			fact2[i]=fact2[i/2]+1;
		
		if(i%3==0)
			fact3[i]=fact3[i/3]+1;
		
		if(i%5==0)
			fact5[i]=fact5[i/5]+1;
	}
	
	//Aici incepe solutia propriu-zisa, ea se bazeaza pe observatia ca C(n,k)=C(n,k-1)*((n-k+1)/k), deci numarul de
	//factori de d vor fi F(n,k)=F(n,k-1)+factd[n-k+1]-factd[k]. Acest F(n,k) il vom calcula folosind insa numai fact2,
	//fact3 si fact5, iar in n2,n3 si n5 tinem numarul curent de factori de 2,3 si 5.
	int n2=0,n3=0,n5=0;
	
	//In sol tinem cate numere de pe randul r sunt divizibile cu d
	int sol=0;
	
	//Programul poate fi imbunatatit pentru a lucra numai pana la mijlocul randului, acesta fiind simetric, insa nu e nevoie
	//de aceasta imbunatatire pentru 100 puncte. In folosirii imbunatatirii acesteia trebuie luat in calcul si faptul ca elementul din
	//mijloc nu are simetric in cazul unui numar impar de elemente
	for(i=1;i<r;i++)
	{
		//Actualizam n-urile
		n2=n2-fact2[i]+fact2[r-i+1];
		
		n3=n3-fact3[i]+fact3[r-i+1];
		
		n5=n5-fact5[i]+fact5[r-i+1];
		
		//Daca d este 2,3 sau 5 atunci pentru nd pozitiv crestem solutiile, acest lucru insemnand ca acel element se imparte la d
		if(d==2 && n2>0)
		{
			sol++;
		}
		else if(d==3 && n3>0)
		{
			sol++;
		}
		else if(d==4 && n2>1) //Pentru d=4, trebuie sa avem minim 2 factori de 2 pentru ca elementul sa fie divizibil cu 4
		{
			sol++;
		}
		else if(d==5 && n5>0)
		{
			sol++;
		}
		else if(d==6 && n2>0 && n3>0) //Pentru d=6, trebuie sa avem minim un factor de 2 si unul de 3
		{	
			sol++;
		}
	}

	//Afisam numarul de elemente de pe randul r divizibile cu d
	fout<<sol<<'\n';
	
	//Inchiderea fisierelor de intrare si iesire
	fin.close();
	fout.close();
	return 0;
}