Problema D - Previsão meteorológica

Este é um problema de interação.
Ao contrário dos outros problemas em que deves fazer leitura de dados e escrita do output, neste problema deves interagir com o avaliador através da implementação de uma função e da interação com as funções fornecidas.

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:

Parte I

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".

Parte II

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 é.

O Problema

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.

Ficheiros para Download

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.

Implementação

Deves submeter um único ficheiro que implementa duas funções:

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.

Exemplo

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) 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 Optámos por retornar 0. Isto é, o nosso programa está a prever que não vai chover.
prever([0, 1, 0, 0, 1], 1) 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 Prevemos que não vai chover no segundo dia.
prever([1, 0, 0, 1, 1], 0) Os sensores 0, 3 e 4 prevêm chuva. A=0, pelo que não choveu no 2º dia (acertámos!).
retornar 1 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.

Restrições

São garantidos os seguintes limites em todos os casos de teste:
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.

Avaliação e Casos de Teste

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

Testes no vosso computador

É 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

Qualificação para a final das ONI'2019
(28/02 a 02/03 de 2019)