International Olympiad in Informatics 2011
22–29 July 2011, Pattaya City, Thailand
PARROTS
Competition Tasks – Day 2 Portuguese 1.3
Parrots
Yanee é uma entusiasta de aves. Desde que Yanee leu sobre IP over Avian Carriers (IPoAC), ela tem passado muito tempo treinando um bando de papagaios inteligentes para levar mensagens a longas distâncias.
O sonho de Yanee é usar suas aves para enviar uma mensagem M para uma terra muito muito distante. Sua mensagem M é uma sequência de N inteiros (não necessariamente distintos), cada um entre 0 e 255, inclusive. Yanee mantém K papagaios especialmente treinados. Todos os papagaios são parecidos; Yanee não consegue distinguí-los. Cada ave é capaz de lembrar um inteiro entre 0 e
R, inclusive.
Inicialmente, ela tentou um esquema simples: para enviar uma mensagem, Yanee cuidadosamente soltou as aves uma a uma da gaiola. Antes que cada ave alçasse vôo, ela ensinou à ave um número da sequência da mensagem, em ordem. Infelizmente, esse esquema não funcionou. Todas as aves chegaram ao destino, mas não necessariamente na ordem em que saíram. Com esse esquema, Yanee conseguiu recuperar todos os números que ela enviou, mas ela não foi capaz de colocá-los na ordem correta.
Para realizar seu sonho, Yanee necessitará de um esquema melhor, e para isso necessita de sua ajuda. Dada uma mensagem M, ela planeja soltar as aves uma a uma como anteriormente. Ela quer que você escreva um programa para executar as seguintes operações separadas:
Primeiro, seu programa deve ler uma mensagem M e transformá-la em uma sequência de no máximo K inteiros entre 0 e R que ela irá ensinar à s aves.
Segundo, seu programa deve ler uma lista de inteiros entre 0 e R recebidos quando as aves chegam ao destino, e então transformá-los de volta para a mensagem original M.
Você pode assumir que todos os papagaios sempre chegam ao destino, e que cada um deles lembra o número que lhe foi ensinado. Yanee ressalta novamente que os papagaios podem chegar em qualquer ordem. Note que Yanee possui apenas K papagaios, portanto a sequência de inteiros entre
0 e R que você produz deve conter no máximo K inteiros.
Tarefa
Escreva dois procedimentos separados. Um deles vai ser usado pelo remetente (encoder) e o outro pelo destinatário (decoder).
O processo é mostrado na seguinte figura:
International Olympiad in Informatics 2011
22–29 July 2011, Pattaya City, Thailand
PARROTS
Competition Tasks – Day 2 Portuguese 1.3
Procedimento encode(N,M) que recebe os seguintes parâmetros: N – o comprimento da mensagem.
M – um vetor de N inteiros representando a mensagem. Você pode assumir que 0
≤
M[i]
≤
255 para 0≤
i<
N.Esse procedimento deve codificar a mensagem M em uma sequência de inteiros entre 0 e R, inclusive, que será enviada utilizando os papagaios. Para relatar a sequência, seu procedimento encode deve chamar o procedimento send(a) para cada inteiro a que deve ser ensinado a uma das aves.
Procedimento decode(N,L,X) que recebe os seguintes parâmetros: N – o comprimento da mensagem original.
L – o comprimento da mensagem recebida (o número de aves que foram enviadas). X – um vetor de L inteiros representando os números recebidos. Os números X[i]
para 0
≤
i<
L são precisamente os números que seu procedimento encode produziu, mas possivelmente rearranjados em uma ordem diferente.Esse procedimento deve recuperar a mensagem original. Para relatar a mensagem, seu procedimento decode deve chamar, na ordem correta, o procedimento output(b) para cada inteiro b da mensagem decodificada.
Note que R e K não são dados como parâmetros de entrada – por favor veja as descrições das subtarefas abaixo.
Para resolver corretamente uma dada subtarefa, seus procedimentos devem satisfazer as seguintes condições:
Todos os inteiros enviados pelo seu procedimento encode devem estar no intervalo especificado na subtarefa.
O número de vezes que seu procedimento encode chama o procedimento send não deve exceder o limite K especificado na subtarefa. Note, por favor, que K depende do
comprimento da mensagem.
O procedimento decode deve recuperar corretamente a mensagem original M e chamar o procedimento output(b) exatamente N vezes, com b igual a M[0], M[1], ..., M[N-1], respectivamente.
Na última subtarefa, sua pontuação variará de acordo com a razão entre os comprimentos da mensagem codificada e da mensagem original.
Exemplo
Considere o caso em que N = 3, e 10
30
M=
20
International Olympiad in Informatics 2011
22–29 July 2011, Pattaya City, Thailand
PARROTS
Competition Tasks – Day 2 Portuguese 1.3
deve chamar o procedimento send da seguinte maneira: send(7) send(3) send(2) send(70) send(15) send(20) send(3)
Quando todos os papagaios chegam ao destino, suponha que obtenhamos a seguinte lista de números: (3, 20, 70, 15, 2, 3, 7). O procedimento decode então será chamado com N=3, L=7, e
3 20 70 15 2 3 X= 7
O procedimento decode deve produzir a mensagem original (10, 30, 20), e deve relatar o resultado chamando o procedimento output da seguinte maneira:
output(10) output(30) output(20)
Subtarefas
Subtarefa 1 (17 pontos)
N = 8, e cada elemento do vetor M é 0 ou 1.
Cada inteiro codificado deve estar no intervalo de 0 a R=65535, inclusive.
O número máximo de vezes que você pode chamar o procedimento send é K=10×N.
Subtarefa 2 (17 pontos)
1
≤
N≤
16. Cada inteiro codificado deve estar no intervalo de 0 a R=65535, inclusive.
International Olympiad in Informatics 2011
22–29 July 2011, Pattaya City, Thailand
PARROTS
Competition Tasks – Day 2 Portuguese 1.3
Subtarefa 3 (18 pontos)
1
≤
N≤
16. Cada inteiro codificado deve estar no intervalo de 0 a R=255, inclusive.
O número máximo de vezes que você pode chamar o procedimento send é K=10×N.
Subtarefa 4 (29 pontos)
1
≤
N≤
32. Cada inteiro codificado deve estar no intervalo de 0 a R=255, inclusive.
O número máximo de vezes que você pode chamar o procedimento send é K=10×N.
Subtarefa 5 (até 19 pontos)
16
≤
N≤
64. Cada inteiro codificado deve estar no intervalo de 0 a R=255, inclusive.
O número máximo de vezes que você pode chamar o procedimento send é K=15×N.
Importante: a pontuação desta subtarefa depende da razão entre o comprimento da mensagem codificada e o comprimento da mensagem original.
Para um dado caso de teste t nesta subtarefa, seja Pt=Lt/Nt a razão entre o comprimento Lt
da mensagem codificada e o comprimento Nt da mensagem original. Seja P o máximo entre
todos os Pt. Sua pontuação para esta subtarefa sera determinada usando as seguintes regras:
Se P
≤
5, você recebe a pontuação máxima de 19 pontos. Se 5
<
P≤
6, você recebe 18 pontos. Se 6
<
P≤
7, você recebe 17 pontos. Se 7
<
P≤
15, sua pontuação é 1 + 2 × (15 - P), arredondada para o inteiro maispróximo.
Se P
>
15 ou qualquer das suas saídas estiver incorreta, sua pontuação é 0. Importante: qualquer solução válida para as subtarefas de 1 a 4 também resolve as subtarefas precedentes. No entanto, devido ao limite alto de K, uma solução válida para a subtarefa 5 pode não resolver subtarefas de 1 a 4. É possível resolver todas as subtarefas usando a mesma solução.
Detalhes de implementação
Limites
Ambiente de correção: No ambiente real de correção, suas submissões serão compiladas em dois programas e e d para serem executadas separadamente. Tanto seu modulo encoder como o seu módulo decoder serão linkados em cada programa executável, mas e chama apenas encode e d chama apenas decode.
International Olympiad in Informatics 2011
22–29 July 2011, Pattaya City, Thailand
PARROTS
Competition Tasks – Day 2 Portuguese 1.3
executar em 2 segundos. O programa d fará chamadas 50 calls ao procedimento decode e deve executar em 2 segundos.
Limite de Memória: 256 MB
Nota: Não há limite explícito para o tamanho da memória de pilha de sistema. Memória de
pilha de sistema conta no total de memória usada.
Interface (API)
Diretório de implementação: parrots/ A ser implementado pelo competidor:
encoder.c ou encoder.cpp ou encoder.pas decoder.c ou decoder.cpp ou decoder.pas
Nota para programadores C/C++: tanto no corretor exemplo como no corretor real,
encoder.c[pp] e decoder.c[pp] são linkados juntamente com o corretor. Portanto, você deve declarar todas as variáveis globais dentro de cada arquivo como estáticas, para evitar interferência com variáveis de outros arquivos.
Interface do competidor: encoder.h ou encoder.pas decoder.h ou decoder.pas Interface do corretor: encoderlib.h ou encoderlib.pas decoderlib.h ou decoderlib.pas
Corretor exemplo: grader.c ou grader.cpp ou grader.pas
O corretor exemplo executa dois turnos (rounds) separados. Em cada turno, ele inicialmente chama encode com os dados recebidos, e então chama decode com a saída que seu procedimento encode produziu. No primeiro turno o corretor não troca a ordem dos inteiros na mensagem codificada. No segundo turno o corretor troca os inteiros em posições pares e ímpares. O corretor real aplicará vários tipos de permutações nas mensagens codificadas. Você pode alterar como o corretor embaralha os dados modificando seu procedimento
shuffle (em C/C++) ou Shuffle (em Pascal).
O corretor exemplo também verifica tanto o intervalo como o comprimento dos dados codificados. Por padrão, ele verifica que os dados codificados estão no intervalo entre 0 e
65535, inclusive, e que o comprimento é no máximo 10×N. Você pode alterar isso ajustando
as constantes channel_range (de 65535 a 255, por exemplo) e max_expansion (de 10 a 15 ou 7, por exemplo).
Entrada do corretor exemplo: grader.in.1, grader.in.2, ...
Note: O corretor exemplo lê da entrada no seguinte formato:
Linha 1: N
Linha 2: uma lista de N números: M[0], M[1], ..., M[N-1]
Saída esperada para o corretor exemplo: grader.expect.1, grader.expect.2, ...