Post on 10-Nov-2018
¡ BOCA/UVa; ¡ Tipos de Erros; ¡ Como Ser Competitivo; ¡ Problemas Ad Hoc; ¡ Programas Híbridos C/C++; ¡ Representação de tipos; ¡ Formas Padrão de Entrada e Saída (I/O); ¡ Compilação Padrão; ¡ Problemas…
¡ O BOCA Online Contest Administrator é um sistema de administração de competições de programação § Disponibiliza os problemas, placar, e troca de mensagens;
§ Suporta usuários remotos; § Permite que os participantes enviem seus códigos-‐fonte;
§ Correção automática ou personalizada; § Interface web.
¡ Os problemas devem ser fornecidos pelos juízes § Na disciplina utilizaremos basicamente problemas de maratonas passadas.
¡ A Universidad de Valladolid, na Espanha, mantém um site (UVa Online Judge) com vários problemas do mesmo tipo dos utilizados em competições de programação § Organizados em diferentes coleções; § A princípio, são 27000 problemas!
¡ Além disso, o site também possui um juiz para correção automática (autojudge) § Você escolhe um problema, cria um programa e envia o código-‐fonte;
§ Rapidamente você recebe a resposta sobre seu programa.
¡ É necessário um cadastro para utilizar o autojudge § Este cadastro é associado a um perfil: ▪ Número de problemas resolvidos; ▪ Respostas erradas; ▪ etc.
¡ Desta forma, basta realizar um cadastro neste site para que o interessado comece a usufruir deste banco de dados organizado.
¡ Existe também um ranking mundial, atualizado constantemente § 123338 programadores (Fevereiro/2012); § O primeiro colocado (Krzysztof Stencel) resolveu 3296
problemas, em 7250 submissões. ¡ Linguagens aceitas:
§ C; § Java; § Pascal; § C++.
¡ A idéia não é abandonar um estilo de programação, porém, adotar um estilo adequado ao trabalho.
¡ Os problemas citados no livro-‐texto desta disciplina (Programming Challenges) estão neste site § Devidamente identificados.
¡ A cada aula, um conjunto de problemas será disponibilizado para que vocês resolvam § Em português; § O aluno escolherá alguns (número estipulado) dos exercícios para resolver.
¡ Só serão avaliados exercícios também aceitos pelo autojudge (UVa ou BOCA) § Tentativas de fraude acarretam em perda de todo e qualquer privilégio;
§ Além da perda da nota. ¡ Exercícios durante as aulas práticas e também para realização durante a semana.
¡ Moodle www.decom.ufop.br/moodle
¡ Site da disciplina (backup) www.decom.ufop.br/toffolo/ensino/bcc402_2011-‐1/
¡ UVa uva.onlinejudge.org/index.php
¡ O autojudge exibe uma mensagem após a correção do código-‐fonte enviado § Accepted (Aceito) ou algum erro;
¡ No caso de erro, uma mensagem mais específica é exibida para que o código-‐fonte seja corrigido e submetido novamente § No entanto, a mensagem nem sempre é específica sobre a localização do erro.
¡ Compile Error: Erro de compilação § O programa não compila.
¡ Runtime Error: Erro de execução § O programa deu pau em algum dos testes realizados; § Note que a bateria de testes é extensa, e embora seu programa
tenha executado normalmente para os testes que você fez, há algo de errado;
§ Procure por erros de memória. ¡ Time Limit Exceeded: Tempo de execução excedido
§ O programa demorou demais a responder; § Não foi avaliado se a resposta está certa ou errada; § Procure por procedimentos pesados ou loops infinitos.
¡ Presentation Error: Saída em formato errado § A resposta dada está em formato errado em relação ao que foi
pedido; § Uma diferença mínima, como uma quebra de linha já é
suficiente; § Note que, neste caso, não foi avaliado se a solução está certa ou
errada. ¡ Wrong Answer: Resposta errada
§ A resposta está errada; § Novamente, a bateria de testes é extensa, e embora seu
programa tenha executado normalmente para os testes que você fez, há algo de errado;
§ Realize testes diferentes.
¡ Memory Limit Exceeded: Memória excedida § O programa requer mais memória do que é permitido para o
problema; § Verifique se a abordagem está correta, cuidado com
recursividade, programação dinâmica e backtracking. ¡ Output Limit Exceeded: Muitos dados na saída
§ O programa produz mais que 4 MB de dados de saída; § Raro.
¡ Restricted Function: Função Restrita § Utilização de chamadas de sistema ou acesso a sistema de
arquivos; § Por isso shell script é proibido.
¡ Others: Outros § Erros incomuns; § Raro de acontecer, mas não impossível; § Neste caso não tem dica…
Dica 1: Digite Rápido e Corretamente
¡ Não é brincadeira, é importante! ¡ Teste a si próprio
§ http://www.typingtest.com § ZEBRA – Africa’s stripped horse
¡ Familiarize-‐se com a posição das teclas § (, ), {, }, [, ], <, >, ’, ”, &, |, !, etc; § Domine o autocomplete de algum editor.
Dica 2: Identifique Rapidamente o Tipo do Problema
¡ Ad Hoc (algoritmos não tradicionais); ¡ Busca Completa; ¡ Dividir e Conquistar; ¡ Guloso; ¡ Programação Dinâmica; ¡ Grafos; ¡ Matemático; ¡ String; ¡ Geometria Computacional; ¡ Outros mais difíceis.
Dica 3: Analise o Algoritmo
¡ Maior profundidade em BCC202; ¡ Veremos o básico necessário
§ Localizar as restrições no enunciado do problema; § Pensar no algoritmo mais simples que funcione; § Realizar análises básicas que convençam que o algoritmo funciona ▪ Antes de começar a codificar!
Dica 4: Domine uma Linguagem de Programação
¡ Devemos dominar pelo menos uma linguagem de programação § Menos tempo olhando em referências; § Usar atalhos, macros, etc; § Usar bibliotecas sempre que possível.
¡ A idéia é, uma vez com a solução em mente, traduzí-‐la em um código livre de erros § E rápido.
Dica 5: Dominar a Arte de Testar
¡ Obviamente, queremos um Accepted § Nossos códigos têm que passar pelos “testes secretos” dois juízes.
¡ Entretanto, nem sempre é possível § Onde foi que eu errei?
Dica 7: Trabalho em Equipe
¡ Pratique programar em papel; ¡ Estratégia “submeter e imprimir”; ¡ Criar casos de teste desafiadores; ¡ Precisa “dar liga”.
¡ Ad Hoc § para isto, para um determinado ato; § para este caso específico; § eventualmente investido em função provisória, para um fim especial.
¡ Problemas Ad Hoc são aqueles cujos algoritmos de solução não recaem em categorias bem estudadas;
¡ Cada problema é diferente do outro § Não existe técnica específica ou genérica para resolvê-‐los.
¡ São os mais divertidos (às vezes frustrantes) § Desafios novos a cada problema.
¡ A solução pode exigir uma estrutura nova ou um conjunto nada usual de laços e condições.
¡ Às vezes requerem combinações especiais raras, ou pelo menos, raramente encontradas;
¡ Exigem leitura cuidadosa do enunciado § A solução pode ser o ataque a cada uma das dicas dadas no enunciado.
¡ Por serem tão livres, é necessário vigiar-‐se para não cair em códigos ineficientes § Por exemplo, cinco laços aninhados…
¡ Problemas Ad Hoc podem ser superficialmente categorizados § Triviais, fáceis, médios… § Jogos (cartas, tabuleiros, etc.); § Combinatórios (Josephus, Palíndromos, Anagramas);
§ Problemas reais/Simulação; § Simplesmente “Ad Hoc”.
Truque de Cartas • Um mágico faz o seguinte truque tendo n cartas do
naipe de espadas com a face para baixo: • Se retirar a carta do topo, a próxima será o ás; • Se retirar duas cartas, a próxima será o 2; • Se retirar três cartas, a próxima será o 3; • … • Cartas retiradas voltam ao fundo das n cartas, menos as viradas.
• Qual é o algoritmo de embaralhamento das cartas?
¡ A linguagem C++ foi criada a partir da linguagem C, mantendo toda a sintaxe desta última § Logo, C é um subconjunto da linguagem C++.
¡ C++ é uma linguagem orientada a objetos, com muitas vantagens sobre C, que é estruturada § Por exemplo a STL; § No entanto, C não caiu em desuso.
¡ É possível criar programas híbridos C/C++ § Por exemplo, criar um arquivo .cpp cujo conteúdo seja um programa em C puro.
¡ Graças ao C++, é possível criar programas C que: § Usem vetores realmente dinâmicos sem calloc e malloc;
§ Usem pilhas, listas, filas, conjuntos, multiconjuntos, mapas, multimapas e etc já codificados;
§ Tratem strings com mais naturalidade. ¡ Os programas podem ser estruturados e ainda assim utilizar objetos pré-‐existentes.
¡ Para criar um programa híbrido, basta criar um código-‐fonte C++ e programar misturando C e C++ § Compilação normal.
¡ Não é uma prática tão comum § Em bcc221 não é permitido.
¡ Salvamos o arquivo com a extensão .cpp, .cxx, .cc ou .C (maiúsculo);
¡ Utilizamos o compilador g++ § g++ arquivo.cpp –o programa
39
// Programa de impressão de texto. #include <iostream> // permite que o programa gere saída de dados na tela using namespace std; // a função main inicia a execução do programa int main() { cout << "Welcome to C++! "<<endl; // exibe a mensagem return 0; // indica que o programa terminou com sucesso } // fim da função main
40
¡ Em todos os problemas que veremos, os dados são lidos da entrada padrão e escritos na saída padrão § Nada de abrir arquivos ou chamadas de sistema.
¡ Nos testes, utilizaremos redirecionamento da entrada § ./programa < entrada.txt
¡ Existem dois aspectos importantes sobre a leitura de dados § O quê deve ser lido? § Até quando ler?
¡ O primeiro diz respeito à formatação dos valores § número inteiro, número real, caractere, string, linha inteira…
¡ O segundo diz respeito ao término da entrada § Número fixo de valores, valor especial ou EOF.
¡ O enunciado do problema deve ser lido atentamente § A codificação da leitura dos dados não deve ser um processo lento.
¡ Em nossos programas híbridos, utilizaremos as instruções/fluxos a seguir: § scanf: Lê dados de acordo com a formatação indicada;
§ cin: Lê dados de acordo com o tipo da variável; § gets: Lê uma linha excluindo o '\n', descarta o '\n' e coloca '\0' no final
§ fgets: Lê uma linha incluindo o '\n' e coloca '\0' no final
scanf("%d", &i); ! cin >> i; ! ¡ i deve ser uma variável inteira; ¡ No scanf:
§ %2d leria apenas um número de no máximo dois dígitos;
§ Para descartarum valor, usamos * § e. g., o código abaixo lê um número, ignora um caractere e lê outro número:
scanf("%d%*c%d", &i1, &i2);
¡ scanf("%c", &c); " "!§ Lê o próximo caractere.
¡ scanf("%13c", s); " "!§ Lê 13 caracteres guardando-‐os no vetor s, sem o '\0'.
¡ scanf(" %c", &c); " "!§ Pula caracteres brancos e lê o caractere seguinte.
¡ c = cin.get();" "!§ Lê o próximo caractere; § Retorna um inteiro ou EOF.
¡ cin.get(c); " " "!§ Lê o próximo caractere; § Retorna NULL=false=zero em caso de erro.
¡ cin >> c; " " "!§ Pula caracteres brancos e lê o caractere seguinte.
¡ gets(s); " "!§ Lê uma linha excluindo o '\n', descarta o '\n' e coloca '\0' no final.
¡ fgets(s,tam,stdin);"!§ Lê uma linha incluindo o '\n' e coloca '\0' no final; § Este '\n’ ao final é um incômodo desnecessário para nossos fins.
¡ cin.getline(s,tam); !§ Lê uma linha excluindo o '\n', descarta o '\n' e coloca '\0' no final;
§ Mais recomendado, pois exclui o '\n'. ¡ cin.get(s,tam); !
§ Lê uma linha excluindo o '\n', mantém o '\n' no buffer e coloca '\0' no final.
¡ cin.getline(s,10000,'$') !§ Lê até chegar a um caractere '$', descartando-‐o, ou até ler 10000 caracteres, o que acontecer primeiro.
¡ scanf("%s", s);"!§ Lê uma palavra incluindo brancos iniciais; § Retorna vazio no fim de arquivo.
¡ scanf(" %s", s); !§ Lê uma palavra pulando brancos iniciais; § Retorna vazio no fim de arquivo.
¡ cin >> s; !§ A variável s deve ser do tipo string; § Lê uma palavra pulando brancos iniciais; § Retorna vazio no fim de arquivo.
¡ cin.ignore(256, ‘\n’); § Lê da entrada até encontrar um ‘\n’, o qual será removido da entrada
¡ Ainda é possível no cin: § Manipular bases númericas ▪ Manipuladores hex, oct, func.
¡ Por exemplo, suponha um programa que deve ler dois números da entrada e calcular o valor absoluto de sua diferença § Ler dados até quando? ▪ Se não foi especificado um critério de parada, os dados são lidos até que acabem.
§ E agora?
¡ Outro cenário frequente é ler linhas de caracteres até que se encontre uma linha em branco § Como diferenciar um ‘\n’ do fim de uma linha de caracteres de um ‘\n’ da linha em branco?
¡ Primeiramente, lemos as linhas de caracteres § Depois, processamos a string para determinar se é uma linha em branco ▪ Caso contrário, extraímos os dados da string usando a instrução sscanf() ou strtok().
¡ Em nossos programas híbridos, recomenda-‐se a utilização das instruções: § printf: Imprime dados no formato especificado (vide próximos slides);
§ cout: Imprime dados no formato especificado pela variável, ou texto entre aspas duplas.
¡ cout<<"texto"; !§ Imprime o texto entre aspas duplas.
¡ cout<<variavel; !§ Imprime o conteúdo da variável.
¡ cout<<conteudo<<endl; !§ Imprime e depois quebra a linha (endl). !
¡ setw § Define o tamanho do campo a ser impresso.
¡ setprecision § Define o número de casas decimais.
¡ setfill § Define o caractere usado para preencher espaços de um campo.
¡ setiosflags § Define a apresentação entre ponto decimal, notação científica, etc.
¡ Estes manipuladores estão definidos na biblioteca iomanip.
Formato Saída Exemplo
c Caractere A
d ou i Inteiro decimal com sinal 392
e Notação científica, usando o caractere e 3.9265e+2
E Notação científica, usando o caractere E 3.9265E+2
f Ponto flutuante decimal 392.65
g Usa o mais curto entre %e e %f 392.65
G Usa o mais curto entre %E e %f 392.65
Formato Saída Exemplo
o Octal com sinal 610
s String Tricolor
u Decimal inteiro sem sinal 7235
x Hexadecimal inteiro sem sinal 7fa
X Hexadecimal inteiro sem sinal (Maiúsculas)
7FA
p Endereço de ponteiro B800:0000
% % %
Tag Descrição Exemplo .nformato Número de casas decimais (n) “.2f”
ninteiro Número de caracteres a serem escritos (n), completa com espaços em branco
“%10d”
0inteiro Número de caracteres a serem escritos, completa com zeros “%010d”
¡ Mantenha a simplicidade § Nada de matar formiga usando tanques de guerra.
¡ Familiarize-‐se com os tipos de dados primitivos § A partir deles quase tudo pode ser criado e resolvido.
¡ Note que o tamanho dos tipos não é definido pela linguagem § Na verdade, depende da arquitetura utilizada ▪ 16 bits, 32 bits, 64 bits…
¡ Para maior precisão, existem estruturas e bibliotecas para números de alta precisão § Por exemplo, a bignum; § Com isso surge a aritmética de inteiros de alta precisão; ▪ Mas isso é assunto para outra aula…
¡ Estar atento aos limites de cada tipo é especialmente importante para evitar erros;
¡ Na descrição da entrada de cada problema, é informado o intervalo de valores que podem ser utilizados na entrada § Por exemplo, se um inteiro da entrada está entre 0 e 3x109, o tipo int não servirá;
§ Consequentemente, um programa que usa o tipo int funcionará para alguns casos e outros não.
¡ C
gcc fonte.c –o destino –lm –lcrypt –O2 –pipe –ansi –DONLINE_JUDGE
¡ C++
g++ fonte.cpp –o destino (eventualmente, –lm)
¡ Todo programa em C deve ter a instrução return 0 em seu final § Caso contrário ocorrerá erro de execução para o autojudge.
¡ Comentários de uma linha não são aceitos.
¡ O editor de textos EMACS causa erros de formatação em arquivos utilizados para teste de entrada § Logo, os testes realizados com estes arquivos são incompatíveis com os utilizados pelo autojudge, criando risco de resposta errada.
¡ O problema 11849 – CD, demonstra (exageradamente) alguns tipos de programadores § O confuso; § O desistente; § O lento; § O competitivo; § O muito competitivo.
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2949
1. Informe o id do problema § Geralmente vem antes do nome do mesmo;
2. Marque corretamente a linguagem de programação utilizada no código;
3. Faça o upload do arquivo correto; 4. Clique em submit.
¡ Top Coder é a maior comunidade para desenvolvimento de software e criação digital § Atendendo pedidos de empresas, são criadas competições de programação;
§ Os competidores recebem royalties sobre suas soluções, baseado nas vendas;
§ Possui um estilo de codificação famoso.
¡ Inclua bibliotecas importantes (adicione suas preferidas) sempre § Mesmo que não vá usar…
#include <algorithm>!#include <cmath> !#include <cstdio> !#include <cstring> !#include <iostream> !#include <map>!#include <queue>!#include <set>!#include <string>!#include <vector>!using namespace std; !
¡ Utilize atalhos para tipos de dados comuns
typedef long long ll; !typedef typedef vector<int> vi; !typedef pair<int, int> ii; !typedef vector<ii> vii;
¡ Simplifique as repetições !#define REP(i, a, b) for (int i = int(a); i <= int(b); i++) !!#define REPN(i, n) REP (i, 1, int(n)) !!#define REPD(i, a, b) for (int i = int(a); i >= int(b); i--) !!#define TRvi(c, it) \ !for (vi::iterator it = (c).begin(); it != (c).end(); it++) !!#define TRvii TRvii(c it) \ !for (vii::iterator it = (c).begin(); it != (c).end(); it++)
¡ Outros atalhos !for (i = ans = 0; i < n; i++)… !// fazer inicialização de uma variável no laço!!while while ((scanf scanf( %d , ("%d", n), n) { !// ler a entrada e fazer o teste do valor ao mesmo tempo! !while (scanf("%d", n) != EOF) { … !// ler a entrada e testar EOF
¡ Outros atalhos (2) § Declarar estruturas de dados maiores que o necessário ▪ Se o tamanho da entrada é conhecido, declare a estrutura maior ainda (no caso de matrizes, por exemplo).
§ Utilize variáveis globais para as estruturas de dados;
§ Evite ponteiros.