- "N" grupos de pessoas, cada um com gi pessoas, passam o dia andando em uma montanha russa.
- Cada viagem da montanha russa suporta um máximo de "k" pessoas.
- A cada viagem os grupos vão entrando até que não caiba um grupo inteiro. Ao final da viagem os grupos voltam para o final da fila, mantendo a ordem.
- Ao longo do dia são feitas "R" viagens; cada pessoa gera uma receita de 1 euro por viagem.
- O problema é determinar a receita total.
Como a capacidade da montanha russa pode chegar a 1.000.000.000 de pessoas, o valor total pode chegar a 10^17. Isto estoura a capacidade de inteiros de 32bits mas cabe nos inteiros de 64 bits (o que eu não percebi inicialmente). O código adiante usa a sintaxe confusa do Visual C++ v6 para os inteiros de 64 bits.
A questão é como evitar ter que ficar somando um a um os grupos para cada viagem. Rabiscando um pouco, percebi que o grupo no início da fila define quantas pessoas vão na viagem e qual grupo ficará no início da fila. Isto pode ser calculado no início para os até 1.000 grupos, simplificando o cálculo para as até 100 milhões de viagens.
Para não correr riscos, tratei separado dois casos particulares:
- Todos os grupos podem ir em uma viagem.
- O primeiro grupo não cabe na montanha russa, impedindo todo mundo de viajar.
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define FALSE 0
- #define TRUE 1
- #define MAX_N 1000
- typedef struct
- {
- unsigned g;
- __int64 sum;
- unsigned next;
- } GROUP;
- GROUP grp [MAX_N];
- void main (void)
- {
- int iCase, nCases;
- int R, k, N;
- int i, j;
- __int64 total;
- scanf ("%d\n", &nCases);
- for (iCase = 1; iCase <= nCases; iCase++)
- {
- scanf ("%d %d %d\n", &R, &k, &N);
- total = 0;
- for (i = 0; i < N; i++)
- {
- scanf ("%d ", &grp[i].g);
- total += grp[i].g;;
- }
- if (total < k)
- {
- // cabem todos
- total = total * R;
- }
- else if (grp[0].g > k)
- {
- // primeiro grupo nao cabe
- total = 0;
- }
- else
- {
- for (i = 0; i < N; i++)
- {
- j = i;
- total = 0;
- while ((total + grp[j].g) <= k)
- {
- total += grp[j].g;
- if (++j >= N)
- j = 0;
- }
- grp[i].sum = total;
- grp[i].next = j;
- }
- total = 0;
- j = 0;
- for (i = 0; i < R; i++)
- {
- total += grp[j].sum;
- j = grp[j].next;
- }
- }
- printf ("Case #%d: %I64d\n", iCase, total);
- }
- }
Nenhum comentário:
Postar um comentário