Cod sursa(job #590627)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 18 mai 2011 21:29:12
Problema Grupuri Scor 2
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.42 kb
#include <iostream>
#include <cstdio>

#define Infinit 1000000000

using namespace std;

long N, K, CS[1000001], A[100001], AMax;
long long NGrupuri;

void Read ()
{
	FILE *fin = fopen ("grupuri.in", "r");
	long i;
	fscanf (fin, "%ld%ld", &K, &N);
	for (i=0; i<N; i++)
	{
		fscanf (fin, "%ld", &A[i]);
		if (A[i]>AMax)
		{
			AMax=A[i];
		}
	}
	fclose (fin);
}

void Type ()
{
	FILE *fout = fopen ("grupuri.out", "w");
	fprintf (fout, "%lld\n", NGrupuri);
	fclose (fout);
}

void CountingSort ()
{
	long i, j;
	for (i=0; i<=AMax; i++)
	{
		CS[i]=0;
	}
	for (i=0; i<N; i++)
	{
		CS[A[i]]++;
	}
	N=0;
	for (i=AMax; i>0; i--)
	{
		for (j=0; j<CS[i]; j++)
		{
			A[N++]=i;
		}
	}
}

inline long Max (long a, long b)
{
	if (a>b)
	{
		return a;
	}
	return b;
}

inline long Min (long a, long b)
{
	if (a>b)
	{
		return b;
	}
	return a;
}

int Possible (long G)
{
	long i, NG=0, k;
	k=G;
	for (i=0; i<N; i++)
	{
		k-=Min(A[i], G);
		if (k<0)
		{
			NG++;
			k=G+k;
		}
		if (k==0)
		{
			NG++;
			k=G;
		}
	}
	if (NG>=G)
	{
		return 1;
	}
	return 0;
}

int main ()
{
	long Left, Right, Middle;
	Read ();
	CountingSort ();
	AMax=A[0];
	Left=1;
	Right=A[0];
	while (Left<=Right)
	{
		Middle=(Left+Right)/2;
		if (Possible (Middle)==1)
		{
			Left=Middle+1;
			NGrupuri=Middle;
		}
		else
		{
			Right=Middle-1;
		}
	}
	Type ();
	return 0;
}