A
Associação Nacional de Meteorologia (ANM) emprega vários
engenheiros que são responsáveis por variadas tarefas. Uma das
tarefas algorítmicas mais comuns é prever um valor, dado um
conjunto de dados relevantes. Neste sentido, a ANM está à procura
de alguém para os ajudar a desenvolver o próximo sistema de
previsão de chuva, e estão a considerar-te a ti.
Em qualquer zona, a ANM tem N sensores de diferentes tipos espalhados pela região. Baseado nos dados dos sensores, o teu objetivo será prever se irá chover numa determinada região ou não, em cada dia, ao longo de T dias. Esta tarefa está divida em duas situações que deves resolver:
Em cada um dos T dias, cada um dos N sensores prevê, baseado em certos dados que recolhe, se choverá ou não no dia seguinte. Adicionalmente, a ANM sabe que pelo menos um dos sensores dá sempre a previsão correta (o mesmo sensor todos os dias), ou seja, consegue sempre prever se choverá ou não, mas a ANM desconhece qual é.
Para cada dia irás receber a previsão de cada sensor, ou seja, ser-te-á dito que para o dia i, o sensor j tem uma previsão se irá chover ou não. Baseado nesta informação, deves fazer a tua previsão se irá chover ou não no dia i. De seguida, irás receber a observação real, ou seja, se realmente choveu ou não no dia i. O processo repete-se então para cada um dos T dias.
A ANM é muito exigente, ou seja, quer que as suas previsões sejam o mais corretas possíveis. Assim, o teu trabalho será bem sucedido se o número de previsões incorretas que fizeres for, no máximo, Q (cujo valor é dado na secção de restrições).
Para desempenhares este trabalho, deverás escrever um programa que irá receber informações como especificado nos parágrafos anteriores e fazer uma previsão. O formato deste programa está explicado abaixo, na secção "Implementação".
A segunda parte da tua tarefa é muito semelhante à da primeira parte, mas com uma pequena diferença. Infelizmente, para algumas zonas, os sensores da ANM não são tão precisos, por isso, não há nenhum que acerta sempre na sua previsão. Ainda assim, a ANM sabe que pelo menos um dos sensores tem uma previsão correta pelo menos 99% das vezes (o mesmo sensor todos os dias), ou seja, existe um sensor que dá previsões erradas no máximo em 1% dos dias. Por exemplo, se T = 5000, o sensor erra no máximo 50 vezes. Novamente, a ANM desconhece qual sensor é.
Dado o número de sensores N numa determinada zona, um número de dias T a prever e uma situação S (que indica a que parte do problema se refere), prever se irá chover em cada dia, ao longo dos T dias, através das previsões dos N sensores, errando no máximo Q vezes.
Podes começar por descarregar os ficheiros correspondentes à tua linguagem (ou um arquivo zip contendo tudo):
Linguagem | Ficheiro a implementar | Ficheiro com avaliador exemplo | Ficheiros auxiliares | Input para avaliador exemplo |
C | resolver.c | avaliador.c | avaliador.h | input.txt / input_large.txt |
C++ | resolver.cpp | avaliador.cpp | ||
Java | resolver.java | avaliador.java | ------ | |
Pascal | resolver.pas | avaliador.pas | avaliadorlib.pas |
Nota que a implementação do avaliador a usar nos testes oficiais será diferente, mas podes esperar o mesmo comportamento. Além disso, é garantido que o avaliador demora no máximo 0.1 segundos a fornecer as previsões dos sensores.
Deves submeter um único ficheiro que implementa duas funções:
iniciar(N, T, S)
, que recebe um
inteiro N, que representa o número de sensores, um
inteiro T, que representa o número de dias a prever, e
um inteiro S, que será 1 ou 2 para referir a que parte
do problema este caso de teste considera. prever(previsoes, A)
, que recebe
uma array/vetor de inteiros previsoes, que representa a
previsão de cada sensor e que será 1 para representar uma
previsão de chuva, e 0 caso contrário, e um inteiro A,
que representa o valor real de chuva no dia anterior, ou seja,
será 1 se no dia anterior choveu e 0 caso contrário. Esta
função deve devolver um inteiro, 0 ou 1, que representa a tua
previsão para o dia atual, baseado nas previsões dos
sensores. Nota que na primeira chamada da função prever(previsoes,
A)
o valor de A será -1, pois ainda não houve um dia
anterior para observar. Para mais informação sobre como
implementar estas funções, vê o exemplo.
Nota que a array previsoes é consistente, ou seja, ao longo de cada dia a posição i desta array refere-se à previsão do sensor i. Por exemplo, se para um caso de teste relativo à parte I acontecer que o sensor 6 for o sensor cuja previsão está sempre correta, a posição 6 da array indica sempre a previsão real.
Para isso deves usar o ficheiro resolver.{c,cpp,java,pas} que descarregaste, colocando no interior das funções o teu código. Podes acrescentar outras funções, mas devem ficar todas neste ficheiro que é o único que deves submeter.
Funções a implementar:
C/C++/Java: | void iniciar(int N, int T, int S); |
Pascal: | procedure iniciar(N : Longint; T : Longint; S : Longint); |
C/C++: | int prever(int previsoes[MAXN], int A); |
Java: | int prever(int[] previsoes, int A); |
Pascal: | function prever(previsoes : array of Longint; A : Longint): Longint; |
Nota que é importante que a função prever(previsoes,
A)
devolva um inteiro 0 ou 1, caso contrário a resposta
será considerada incorreta.
A vossa função não deve ler nem escrever para os canais de entrada/saída padrão.
Imagina que há N=5 sensores e que se pretende prever se chove ou não ao longe de T=3 dias. Supõe ainda que estamos perante a situação da Parte S=1.
Uma possível execução seria a seguinte (com a ordem das chamadas a ser de cima para baixo):
Invocação | Dia | Descrição |
iniciar(5, 3, 1) | Inicialização. N=5, T=3 e S=1 | |
prever([0, 1, 0, 1, 0], -1) | 1º | Os sensores 0, 2 e 4 prevêm que não vai chover, enquanto que os sensores 1 e 3 prevêm que vai chover. A=-1, dado que este é o primeiro dia. |
retornar 0 | 1º | Optámos por retornar 0. Isto é, o nosso programa está a prever que não vai chover. |
prever([0, 1, 0, 0, 1], 1) | 2º | Os sensores 1 e 4 prevêm chuva. A=1, o que significa que choveu no primeiro dia (pelo que a nossa previsão estava incorreta). |
retornar 0 | 2º | Prevemos que não vai chover no segundo dia. |
prever([1, 0, 0, 1, 1], 0) | 3º | Os sensores 0, 3 e 4 prevêm chuva. A=0, pelo que não choveu no 2º dia (acertámos!). |
retornar 1 | 3º | Prevemos que vai chover no terceiro dia. |
Neste exemplo específico o sensor 3 estava sempre correto, tendo chovido no 1º e 3º dia. Assim, acertamos a previsão no dia 2 e 3, ou seja, apenas erramos uma previsão. Se Q for maior ou igual a 1 então esta execução teria tido sucesso.
1 ≤ N ≤ 100 | Número de sensores. | |
1 ≤ T ≤ 5 000 | Número de dias a prever. |
Os valores de Q, o número máximo de previsões erradas, são dados na secção seguinte, assim como os valores de S, a parte do problema.
Os casos de teste deste problema estarão agrupados em conjuntos de testes. Ao contrário dos restantes problemas, para obter pontuação é necessário acertar todos os casos de teste de um grupo de casos, nesse caso terão a pontuação completa relativa a esse grupo. Se falharem um ou mais casos de um grupo, a pontuação atribuída relativa a esse grupo será nula.
Cada grupo tem um número de pontos associado e um conjunto de restrições adicionais. Os grupos são os seguintes:
Grupo | Número de Pontos | Restrições adicionais |
---|---|---|
1 | 5 | S = 1, Q = 2600 |
2 | 20 | S = 1, Q = 150 |
3 | 25 | S = 1, Q = 15 |
4 | 10 | S = 2, Q = 400 |
5 | 20 | S = 2, Q = 250 |
6 | 20 | S = 2, Q = 150 |
É disponibilizado um avaliador exemplo em cada linguagem (avaliador.{c,cpp,java,pas}) que pode ser utilizado para testar a vossa submissão. Para C/C++/Pascal está ainda disponível um ficheiro auxiliar (para C/C++ o avaliador.h e para Pascal o avaliadorlib.pas). Este avaliador não corresponde ao utilizado pelo sistema de avaliação.
Este avaliador começa por receber como input um inteiro N, um inteiro T, um inteiro S e um inteiro Q, correspondendo, respetivamente, ao número de sensores, ao número de dias, à parte do problema (1 ou 2) e ao número máximo de previsões erradas. Seguem-se T linhas, uma para cada dia j, cada uma com N inteiros 0 ou 1, separados por espaço, um para cada sensor i, sendo o i-ésimo inteiro da j-ésima linha 1 se o sensor i prevê que vai chover no dia j, e 0 caso contrário. Segue-se ainda uma linha com T inteiros 0 ou 1, separados por espaços, sendo que o j-ésimo desses inteiros é 1 se choveu no dia j, e 0 caso contrário.
O avaliador irá automaticamente invocar a função iniciar(N,T,S)
, por vocês implementada, uma vez, e invocará seguidamente a função prever(previsoes, A)
T vezes, uma para cada dia. O avaliador indicará no final quantas previsões falharam e se a resposta é considerada correta ou não.
Disponibilizamos dois ficheiros:
Estes dois testes serão corridos pelo Mooshak durante a Qualificação para garantir que o programa compila e funciona em testes simples, mas os testes finais que serão usados para atribuir a pontuação ao vosso programa serão diferentes.
Um exemplo de teste na tua máquina (supondo que tens os compiladores oficiais instalados) seria o seguinte:
Linguagem | Compilar | Executar com o exemplo |
C | gcc -Wall avaliador.c resolver.c | ./a.out < input.txt |
C++ | g++ -Wall avaliador.cpp resolver.cpp | ./a.out < input.txt |
Java | javac avaliador.java resolver.java | java avaliador < input.txt |
Pascal | fpc avaliador.pas | ./avaliador < input.txt |