program Vestibular;
{-- Executar lendo arquivo: a.out <vestibular.dat   }

const NOPCOES = 3; NCURSOS = 7;
type
  TipoChave = 0..999;
  TipoItem  = record
                Chave    : TipoChave;
                NotaFinal: 0..10;
                Opcao    : array [1..NOPCOES] of 1..NCURSOS;
              end;
  TipoApontador = ^TipoCelula;
  TipoCelula    = record
                    Item: TipoItem;
                    Prox: TipoApontador;
                  end;
  TipoLista     = record
                    Primeiro: TipoApontador;
                    Ultimo  : TipoApontador;
                  end;

var Registro     : TipoItem;
    Classificacao: array [0..10] of TipoLista;
    Aprovados    : array [1..NCURSOS] of TipoLista;
    Reprovados   : TipoLista;
    Vagas        : array [1..NCURSOS] of integer;
    Passou       : boolean;
    i, Nota      : integer;
 
procedure FLVazia (var Lista: TipoLista);
begin
  new (Lista.Primeiro);
  Lista.Ultimo := Lista.Primeiro; Lista.Primeiro^.Prox := nil;
end; { FLVazia }

function Vazia (Lista: TipoLista): boolean;
begin Vazia := Lista.Primeiro = Lista.Ultimo; end; { Vazia }

procedure Insere (x: TipoItem; var Lista: TipoLista);
begin
  new (Lista.Ultimo^.Prox); Lista.Ultimo := Lista.Ultimo^.Prox;
  Lista.Ultimo^.Item := x;  Lista.Ultimo^.Prox := nil
end; { Insere }

procedure Retira (p:TipoApontador;var Lista:TipoLista;var Item: TipoItem);
{---Obs.: o item a ser retirado e o seguinte ao apontado por  p --- }
var q: TipoApontador;
begin
  if Vazia (Lista) or (p = nil) or (p^.Prox = nil)
  then writeln ('Erro: Lista vazia ou posicao nao existe')
  else begin
       q := p^.Prox; Item := q^.Item; p^.Prox := q^.Prox;
       if p^.Prox = nil then Lista.Ultimo := p;
       dispose (q);
       end;
end; { Retira }
 
procedure Imprime (Lista: TipoLista);
var Aux: TipoApontador;
begin
  Aux := Lista.Primeiro^.Prox;
  while Aux <> nil do
    begin writeln (Aux^.Item.Chave); Aux := Aux^.Prox; end;
end; { Imprime }

procedure LeRegistro (var Registro: TipoItem);
{---os valores lidos devem estar separados por brancos---}
var i: integer;
begin
  read (Registro.Chave, Registro.NotaFinal);
  if Registro.Chave <> 0
  then for i := 1 to NOPCOES do read (Registro.Opcao[i]);
  readln;
end; { LeRegistro }


begin {---Programa principal---}
  for i := 1 to NCURSOS do read (Vagas[i]); readln;
  for i := 0 to 10 do FLVazia(Classificacao[i]);
  for i := 1 to NCURSOS do FLVazia(Aprovados[i]);
  FLVazia(Reprovados); LeRegistro(Registro);
  while Registro.Chave <> 0 do
    begin
    Insere(Registro, Classificacao[Registro.NotaFinal]);
    LeRegistro(Registro);
    end;
  for Nota := 10 downto 0 do
    while not Vazia(Classificacao[Nota]) do
      begin
      Retira(Classificacao[Nota].Primeiro,Classificacao[Nota],Registro);
      i := 1; Passou := false;
      while (i <= NOPCOES) and not Passou do
        begin
        if Vagas[Registro.Opcao[i]] > 0
        then begin
             Insere(Registro, Aprovados[Registro.Opcao[i]]);
             Vagas[Registro.Opcao[i]] := Vagas[Registro.Opcao[i]] - 1;
             Passou := true;
             end;
        i := i + 1;
        end;
      if not Passou then Insere(Registro, Reprovados);
      end;
  for i := 1 to NCURSOS do
    begin
    writeln('Relacao dos aprovados no Curso', i:2);
    Imprime(Aprovados[i]);
    end;
  writeln('Relacao dos reprovados');
  Imprime(Reprovados);
end.

