Solução por Rogério Júnior
Para ver o problema original, clique aqui.
Seja . O enunciado nos diz que .
Suponha . Como só há valores possíveis para um qualquer mas há vizinhos e cada um deles com o seu valor de , pelo Princípio da Casa dos Pombos, há pelo menos dois vizinhos e ( em que . Logo, . Logo, os índices entre e são solução.
Suponha agora . Se houver pelo menos dois vizinhos com mesmo , aplicamos a mesma solução acima. Se não existirem tais vizinhos, então todos eles têm valores distintos. Mas só existem possíveis valores e vizinhos, logo, todos os possíveis valores aparecem, logo, existe , tal que , logo os índices de a são solução.
Acabamos de provar que sempre conseguimos encontrar uma resposta apenas com uma sequência contígua de índices, o que facilita muito o problema. Para cada caso, vamos criar um vetor em que . Basta salvarmos o valor de cada em e depois percorrermos o vetor acumulando, em cada casa, o valor da casa anterior (que já teria acumulado o de todas as outras anteriores), e guardarmos módulo . Feito isso, vamos percorrer o vetor, guardando todos os valores que já apareceram em um vetor , de modo que, quando estamos analisando a casa do vetor , . Logo, se , então encontramos vizinhos com mesmo e basta imprimirmos os índices entre eles. Caso contrário (não existe , o que podemos representar com , marco e continuo a percorrer. Note que, se marcarmos que , então, mesmo quando e todos os forem distintos, o programa encontrará solução pois, ao chegar em , tal que , ele verá que , e imprimirá os índices de a . Segue o código para melhor entendimento.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <cstring> | |
#define MAXN 100100 | |
int c, n, s[MAXN], resto[MAXN]; | |
int main(){ | |
// para cada caso | |
while(scanf("%d %d", &c, &n)and n and c){ | |
// defino todos os valores de resto para -1, ou seja, não encontrados | |
memset(resto, -1, sizeof resto); | |
// caso especial de n=c, e todos os s_i serem distintos | |
resto[0]=0; | |
// leio a entrada e salvo em s | |
for(int i=1; i<=n; i++) scanf("%d", &s[i]); | |
// para cada vizinho | |
for(int i=1; i<=n; i++){ | |
// descubro o valor real de seu s, acumulando o s anterior | |
s[i]+=s[i-1]; | |
// e guardando módulo c | |
s[i]%=c; | |
// se esse resto já foi encontrado no vetor, na posição k | |
if(resto[s[i]]>=0){ | |
// imprimo os índices de k+1 a i | |
// com o cuidado de não imprimir um espaço a mais no final | |
printf("%d", resto[s[i]]+1); | |
for(int j=resto[s[i]]+2; j<=i; j++) printf(" %d", j); | |
printf("\n"); | |
// e paro de percorrer o vetor | |
break; | |
} | |
// caso contrário, guardo o novo resto encontrado | |
resto[s[i]]=i; | |
} | |
} | |
return 0; | |
} |