Pesquisar este blog

Livros Recomendados

Mostrando postagens com marcador Beginner. Mostrar todas as postagens
Mostrando postagens com marcador Beginner. Mostrar todas as postagens

quarta-feira, 24 de março de 2021

URI (BEECROWD) - 3089 - Presentes de Natal - Iniciante - C e C++

Novo post! Esse é sobre o problema "Presentes de Natal", da plataforma URI/BEECROWD.  Resolvi ele em C e C++. Veja abaixo como isso foi feito!

Plataforma: URI (BEECROWD)

Problema3089

Linguagens: C e C++


Solução:

Utilizei basicamente a mesma solução, mas em cada linguagem ela usa estruturas e funções diferentes devido às particularidades de cada uma.

Após a declaração das variáveis, todo código fica em um laço infinito que tem como primeira instrução a leitura do valor n, um inteiro com sinal. A interrupção do laço só ocorre no caso do valor de n ser zero. Enquanto isso não acontece, todos os casos são válidos e sua lógica acontece na sequência.

Feita esta explicação inicial, o "núcleo da solução" é o seguinte: lê-se 2n valores (inteiros com sinal) e coloca-se estes valores em uma estrutura. Após todas as leituras é necessário ordenar os valores e gerar os pares de valores. Esses pares também são ordenados, assim fica fácil obter os pares mais caros e mais baratos. Nesse laço de repetição que soma os pares é necessário utilizar dois índices, um iniciando no primeiro elemento (índice 0) e outro no último (2n-1). A estrutura que armazena os pares deverá ser ordenada também, assim ela terá nas posições 0 e n-1 os valores mais alto e baixo, respectivamente. Basta imprimir os valores dessas posições.

Código em C:

Para cumprir a solução foi necessário declarar p e pares como arrays e utilizar qsort (da biblioteca stdlib.h) para ordená-los. Criou-se também uma função de comparação (cmpfunc), como pede a assinatura da qsort. 

A função memset foi utilizada para garantir que todas as posições de p e parese stejam com o valor padrão zero a cada iteração, evitando que as estruturas ainda tenham lixo da iteração anterior.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int cmpfunc (const void * a, const void * b) {
   return ( *(int*)a - *(int*)b );
}

int main() {
    
    int n, i, j;
    int p[1000000], pares[1000000];
    
    while (1) {
        
        scanf("%d", &n);
        
        if (!n)
            break;
        
        for (i = 0; i < 2 * n; i++)
            scanf("%d", &p[i]);
        
        qsort(p, 2*n, sizeof(int), cmpfunc);
        
        for (i = 0, j = 2 * n - 1; i < n; i++, j--)
            pares[i] = p[i] + p[j];
        
        qsort(pares, n, sizeof(int), cmpfunc);
        printf("%d %d\n", pares[n-1], pares[0]);
        
        memset(p, 0, sizeof(p));
        memset(pares, 0, sizeof(pares));
    }

    return 0;
}

Código em C++:

Utilizando a estrutura vector o código em C++ fica bem mais simples em relação ao código em C. Não é necessário implementar um algoritmo de ordenação, podendo utilizar o algoritmo sort, disponível na biblioteca algorithm. Para remover todos os elementos dos vectors p e pares, utiliza-se a função clear. O acesso ao vector por índice também é diferente. Pode-se fazê-lo por meio do at(indice), mas há casos em que nem precisamos indicar o índice. Quando queremos o primeiro e o último elemento, podemos fazer o acesso por meio da função front e da função back, respectivamente.

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

int main() {
    
    int n, meio, i, j, v;
    vector<int> p, pares;
    
    while (true) {
        
        cin >> n;
        
        if (!n)
            break;
        
        for (i = 0; i < 2 * n; i++) {
            cin >> v;
            p.push_back(v);
        }
        
        sort(p.begin(), p.end());
        
        meio = p.size() / 2;
        
        for (i = 0, j = p.size()-1; i < p.size()/2; i++, j--)
            pares.push_back(p.at(i) + p.at(j));
        
        sort(pares.begin(), pares.end());
        cout << pares.back() << " " << pares.front() << endl;
        
        p.clear();
        pares.clear();
    }

    return 0;
}

URI (BEECROWD) - 3084 - Relógio Antigo - Iniciante - C e C++

Mais um exercício do BEECROWD pra vocês! Esse exercício era uma conversão simples. É bom pra quem quer aprender um pouco sobre casting (coerção) de tipos. Outro ponto a ser analisado neste exercício é a formatação da saída, pois ele tem algumas particularidades. Então bora ver os códigos de solução! O exercício foi resolvido em C e C++.

Plataforma: URI (BEECROWD)

Problema3084

Linguagens: C e C++


Solução:

Código em C:

#include <stdio.h>

int main() {
    
    int h, m, respostaH, respostaM;
    
    while (scanf("%i %i", &h, &m) != EOF)
        printf("%02i:%02i\n", (int) h / 30, (int) m / 6);

    return 0;
}

Código em C++:

#include <iostream>
#include <iomanip>

using namespace std;

int main() {
    
    int h, m;
    
    while (cin >> h >> m)
        cout << setw(2) << setfill('0') << (int) h / 30 << ":" << setw(2) << setfill('0') << (int) m / 6 << endl;

    return 0;
}

URI (BEECROWD) - 3076 - Exercício de História - Iniciante - C

Plataforma: URI (BEECROWD)

Problema3076


Linguagens: C e C++


Solução:

Nesse exercício usei a mesma lógica tanto no código em C quanto em C++. Para saber o século do ano, basta dividir o ano por 100. No entanto, existe um ponto a ser tratado: o ano 2000 faz parte do século 20, e o ano 2001 faz parte do século 21. A virada de século sempre acontece no ano 1.

Código em C:

Com base no texto acima, a solução diz que precisamos dividir o ano por 100. Se o ano não tiver resto zero, isso significa que é necessário ainda aumentar um século. Por exemplo, 2001 / 100 = 20. O valor de século passa a ser 20. Como o resto de 2001 % 100 é diferente de zero, incrementa-se um à variável século: era 20, passa a ser 21.

#include <stdio.h>

int main() {
    
    int ano, seculo;
    
    while (scanf("%i", &ano) != EOF) {
        
        seculo = ano / 100;
        
        if (ano % 100 != 0)
            seculo++;
        
        printf("%i\n", seculo);
        
    }
    
    return 0;
}

Código em C++:

Na solução em C++ já foi feito o cálculo 1+ano/100, pois de todas as possibilidades, na maioria delas vai ser acrescentado 1 ao século (só não vai quando o ano terminar em zero). Assim, faz-se depois o teste para saber se o resto da divisão inteira entre ano e 100 é zero; neste caso, decrementa-se a variável século.


#include <iostream>
using namespace std; int main() { int ano, seculo; while(cin >> ano) { seculo = 1 + ano / 100; if (ano % 100 == 0) seculo--; cout << seculo << endl; } return 0; }

URI (BEECROWD) - 3065 - Calculando - Iniciante - C++

Mais um desafio resolvido da plataforma BEECROWD! O exercício "Calculando" é bem simples, de categoria iniciante.  Basicamente toda lógica está dentro de um for, onde também utilizei um operador ternario. Veja a solução abaixo!

Plataforma: URI (BEECROWD)

Problema3065


Linguagem: C++


Solução:

#include <iostream>

using namespace std;

int main() {
    
    int n, i, v, r, c = 1;
    char op;
    
    while (cin >> n) {
        
        if (n == 0)
            return 0;
            
        cin >> r;
        for (i = 1; i < n; i++) {
            cin >> op >> v;
            r += op == '+'? v : -v;
        }
        
        cout << "Teste " << c++ << endl << r << endl << endl;
    }
    
    return 0;
    
}

URI (BEECROWD) - 3065 - Calculando - Iniciante - C

Olá, pessoal! Posto aqui a solução para o desafio Calculando, da plataforma BEECROWD (antiga URI).

Plataforma: URI (BEECROWD)

Problema3065


Linguagem: C


Solução:

Note no código que a parte mais importante está no while interno. A comparação op == 43 é feita porque 43 é o código ASCII do operador de soma (caractere "+"). Assim, se o operador for de soma, faz a conta r + v; caso contrário faz r - v. Creio que essa seja a parte mais importante do código. Claro, quem quiser pode fazer um if direto, aqui eu quis fazer com o operador ternário por achar que fica simples de resolver em uma linha só.

#include <stdio.h>
int main() {
    int n, v, r, c = 1;
    char op;
    while (scanf("%d", &n)) {
        if (n == 0)
            return 0;

        scanf("%d", &r);
        while (n-- > 1) {
            scanf("%c%d", &op, &v);
            r += op == 43? v : -v;
        }
        printf("Teste %d\n%d\n\n", c++, r);
    }
    return 0;
}

URI (BEECROWD) - 3055 - Nota Esquecida - Iniciante - C e C++

Mais uma solução de exercício, dessa vez do "Nota Esquecida", iniciante, número 3055. Esse foi bem fácil!

Plataforma: URI (BEECROWD)

Problema3055


Linguagens: C e C++


Solução:

Não tem muito mistério pra resolver esse problema. É necessário ler dois valores (chamei eles de nota1 e media nas duas soluções) e imprimir o dobro da média menos nota1. Por entender que a adição é um cálculo mais simples, preferi calcular o dobro como media + media, mas você pode fazer 2 * media se preferir. Basta imprimir esse valor (e a quebra de linha) e o exercício está correto e pronto para ser aceito!

Código em C:

#include <stdio.h>

int main() {
    
    int nota1, media;
    scanf("%i %i", &nota1, &media);
    printf("%i\n", media + media - nota1);
    
    return 0;
}

Código em C++:


#include <iostream>

using namespace std;

int main() {
    
    int nota1, media;
    cin >> nota1 >> media;
    
    cout << media + media - nota1 << endl;
    
    return 0;
}

terça-feira, 23 de março de 2021

URI (BEECROWD) - 3053 - Jogo Dos Copos - Iniciante - C e C++

Mais um exercício resolvido em C e C++ da plataforma BEECROWD. Veja abaixo as soluções.

Plataforma: URI (BEECROWD)

Problema3053

Linguagens: C e C++

Solução:

Código em C:

#include <stdio.h>

int main() {
    
    int n, troca;
    char pos;
    scanf("%d %c", &n, &pos);
    
    while (n--) {
        
        scanf("%d", &troca);
        
        if (troca == 1 && (pos == 'A' || pos == 'B'))
            pos = (pos == 'A'? 'B' : 'A');
        else if (troca == 2 && (pos == 'B' || pos == 'C'))
            pos = (pos == 'B'? 'C' : 'B');
        else if (troca == 3 && (pos == 'A' || pos == 'C'))
            pos = (pos == 'C'? 'A' : 'C');
    }
    
    printf("%c\n", pos);

    return 0;
}

Código em C++:

#include <iostream>

using namespace std;

int main() {
    
    int n, troca;
    char pos;
    cin >> n >> pos;
    
    while (n--) {
        
        cin >> troca;
        
        if (troca == 1 && (pos == 'A' || pos == 'B'))
            pos = (pos == 'A'? 'B' : 'A');
        else if (troca == 2 && (pos == 'B' || pos == 'C'))
            pos = (pos == 'B'? 'C' : 'B');
        else if (troca == 3 && (pos == 'A' || pos == 'C'))
            pos = (pos == 'C'? 'A' : 'C');
    }
    
    cout << pos << endl;

    return 0;
}

URI (BEECROWD) - 3047 - A idade de Dona Mônica - Iniciante - C e C++

Mais um exercício que disponibilizo as soluções em C e C++. Veja na sequência.

Plataforma: URI (BEECROWD)

Problema3047


Linguagens: C e C++


Solução:

A lógica aplicada para obter o aceite foi a mesma em ambas as linguagens. O valor de filho3 será monica - filho1 - filho2. Os testes são realizados para saber que filho precisa ser impresso na tela.

Código em C:

#include <stdio.h>

int main() {
    
    int monica, filho1, filho2, filho3;
    
    scanf("%i %i %i", &monica, &filho1, &filho2);
    filho3 = monica - filho1 - filho2;
    
    if (filho1 >= filho2 && filho1 >= filho3)
        printf("%i\n", filho1);
    else if (filho2 >= filho1 && filho2 >= filho3)
        printf("%i\n", filho2);
    else
        printf("%i\n", filho3);

    return 0;   
}

Código em C++:

Uma pequena diferença aqui é que coloquei cout << endl (a quebra de linha) depois de tudo, só pra não escrever "<< endl" ao final de cada cout. Isso seria o equivalente a fazer as escritas em C sem o "\n" e, no fim do código, criar um printf("\n");.

#include <iostream>

using namespace std;

int main() {
    
    int monica, filho1, filho2, filho3;
    
    cin >> monica >> filho1 >> filho2;
    filho3 = monica - filho1 - filho2;
    
    if (filho1 >= filho2 && filho1 >= filho3)
        cout << filho1;
    else if (filho2 >= filho1 && filho2 >= filho3)
        cout << filho2;
    else
        cout << filho3;
        
    cout << endl;

    return 0;   
}

URI (BEECROWD) - 3046 - Dominó - Iniciante - C e C++

Mais um exercício de nível iniciante resolvido! Dessa vez o exercício "Dominó". Bastava colocar uma fórmula no comando de escrita e o aceite vinha. Veja abaixo.

Plataforma: URI (BEECROWD)

Problema3046

Linguagens: C e C++


Solução:

Código em C:

#include <stdio.h>

int main() {
    
    int n;
    scanf("%i", &n);
    printf("%i\n", (n+1) * (n+2) / 2);

    return 0;
}

Código em C++:

#include <iostream>

using namespace std;

int main() {
    
    int n;
    cin >> n;
    cout << (n+1) * (n+2) / 2 << endl;

    return 0;
}

URI (BEECROWD) - 3040 - A Árvore de Natal - Iniciante - C e C++

Buenas! Solucionei aqui o exercício "A Árvore de Natal", da plataforma BEECROWD (antiga URI).  O foco desse exercício é estrutura de seleção com expressões lógicas. Veja a seguir as soluções em duas linguagens de programação.

Plataforma: URI (BEECROWD)

Problema3040


Linguagens: C e C++


Solução:

Nesse exercício basta ler os valores h, d e g, todos declarados como inteiro com sinal. É necessário testar quatro condições:

  • h precisa ser maior ou igual a 200
  • h precisa ser menor ou igual a 300
  • d precisa ser maior ou igual a 50
  • g precisa ser maior ou igual a 150
Se as quatro condições forem satisfeitas, a resposta é Sim, caso contrário é Não. Para juntar as quatro condições em uma só, cria-se uma expressão lógica com todas elas juntas, utilizando o operador lógico E. É necessário quebrar a linha no comando de escrita.

Código em C:

#include <stdio.h>

int main() {
    int n, h, d, g;
    scanf("%d", &n);
    
    while (n--) {
        scanf("%d %d %d", &h, &d, &g);
        
        if (h >= 200 && h <= 300 && d >= 50 && g >= 150)
            printf("Sim\n");
        else
            printf("Nao\n");
    }

    return 0;
}

Código em C++:

Aqui, poder-se-ia utilizar o operador "and" em vez de "&&". É exatamente a mesma coisa, uma questão de estilo, apenas.

#include <iostream>

using namespace std;

int main() {
    int n, h, d, g;
    cin >> n;
    
    while (n--) {
        cin >> h >> d >> g;
        
        if (h >= 200 && h <= 300 && d >= 50 && g >= 150)
            cout << "Sim" << endl;
        else
            cout << "Nao" << endl;
    }

    return 0;
}

URI (BEECROWD) - 3039 - Brinquedos do Papai Noel - Iniciante - C e C++

Nesse post eu trago a solução do problema Brinquedos do Papai Noel, do BEECROWD. Dá pra fazer de algumas formas diferentes. Veja na sequência do post como eu obtive aceite nas linguagens de programação C e C++. Boa leitura!

Plataforma: URI (BEECROWD)

Problema3039


Linguagens: C e C++


Solução:

Mais um exercício que resolvi aplicando a mesma lógica em C e C++. A ideia que pensei foi a seguinte: lê todos os dados e verfica se o último caractere da linha é 'F', ou seja, o caractere da posição tamanho-1. Sempre que for 'F', incrementa a variável bonecas. Isso é suficiente, pois tendo o total de crianças e o número de 'F', sabemos também quantos 'M' são, é claro, assumindo que as entradas de dados respeitam a premissa de informar só 'F' ou 'M'.

Código em C:

Para resolver em C, dessa vez o que fiz de diferente foi criar um ponteiro para char (criancas) com alocação de 256 vees o tamanho de um char, assim o ponteiro apontará para um texto com no máximo este tamanho. Outro ponto interessante é o uso do '\0', que é o caractere zero. Este caractere é normalmente usado como terminador de string, portanto, quando obtém-se '\0' é porque chegou ao final da cadeia de caracteres.

#include <stdio.h>

int main() {
    
    int numCriancas, i = 0, bonecas = 0;
    
    scanf("%d ", &numCriancas);
    
    while (i++ < numCriancas) {
        
        char *criancas = (char *) malloc(sizeof(char) * 256);
        int tamanho = 0;
        int j = 0;
        
        gets(criancas);
        
        while (criancas[j++] != '\0')
            tamanho++;
        
        if (criancas[tamanho-1] == 'F') bonecas++;
        
    }
    
    printf("%i carrinhos\n%i bonecas\n", numCriancas - bonecas, bonecas);
    
    return 0;
}

Código em C++:

Solução bastante parecida com a de C. Na verdade, a lógica aplicada foi a mesma, muda apenas a forma de fazer algumas coisas. Por exemplo, não usei ponteiro de char com alocação via malloc, mas apenas declarei criancas como string. Os comandos de entrada (std::cin) e saída (std::cout) também são diferentes.

#include <iostream>

using namespace std;

int main() {
    
    int numCriancas, i = 0, bonecas = 0;
    
    cin >> numCriancas;
    cin.ignore();
    
    while (i++ < numCriancas) {
        
        string criancas;
        int tamanho = 0;
        int j = 0;
        
        getline(cin, criancas);
        
        while (criancas[j++] != '\0')
            tamanho++;
        
        if (criancas[tamanho-1] == 'F') bonecas++;
        
    }
    
    cout << numCriancas - bonecas << " carrinhos" << endl;
    cout << bonecas << " bonecas" << endl;
    
    return 0;
}

URI (BEECROWD) - 3037 - Jogando Dardos Por Distância - Iniciante - C e C++

Resolvendo o problema "Jogando Dardos por Distância" e postando aqui pra vocês, em C e C++! Boa leitura!


Plataforma: URI (BEECROWD)

Problema3037

Linguagens: C e C++


Solução:

A ideia dessa solução foi calcular a pontuação do João e depois a da Maria. No fim, bastava comparar as pontuações, se a de João fosse maior, ele ganha, se não for, ela ganha. Utilizei o pós-incremento nos whiles em C e C++ só pra não precisar colocar o incremento na última instrução do bloco, achei que assim ficaria mais fácil. Espero que tenham entendido o código!

Código em C:

#include <stdio.h>

int main() {
    
    int N, i = 0, pontosJoao, pontosMaria;

    scanf("%i", &N);
    

    while (i++ < N) {
        
        int j = 0, X, D;
        
        pontosJoao = 0;
        pontosMaria = 0;
        
        while (j++ < 3) {
            
            scanf("%i %i", &X, &D);
            pontosJoao += X * D;
            
        }
        
        j = 0;
        
        while (j++ < 3) {
            
            scanf("%i %i", &X, &D);
            pontosMaria += X * D;
            
        }
        
        if (pontosJoao > pontosMaria) printf("JOAO\n");
        else printf("MARIA\n");
        
    }

    return 0;
}

Código em C++:

#include <iostream>

using namespace std;

int main() {
    
    int N, i = 0, pontosJoao, pontosMaria;

    cin >> N;

    while (i++ < N) {
        
        int j = 0, X, D;
        
        pontosJoao = 0;
        pontosMaria = 0;
        
        while (j++ < 3) {
            
            cin >> X >> D;
            pontosJoao += X * D;
            
        }
        
        j = 0;
        
        while (j++ < 3) {
            
            cin >> X >> D;
            pontosMaria += X * D;
            
        }
        
        if (pontosJoao > pontosMaria) cout << "JOAO" << endl;
        else cout << "MARIA" << endl;
        
    }

    return 0;
}

Postagem em destaque

URI (BEECROWD) - 2158 - Helping Uncle Cláudio (Ajudando o Tio Cláudio) - Matemática - C, C++ e Haskell

Buenas! Estou aqui mais uma vez para resolver um problema de Matemática! Agora tenho resolvido alguns dessa categoria, pra que vocês possam ...

Postagens mais visitadas