Pesquisar este blog

Livros Recomendados

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

domingo, 17 de dezembro de 2023

URI (BEECROWD) - 2567 - Vírus - Ad-Hoc - C, C++ e Haskell

Aqui vai mais uma solução, pessoal! O problema Vírus ainda não tinha sido resolvido por mim.  Ele é bem simples, basicamente precisa usar ordenação. Fiz ele em três linguagens, aquelas três que eu mais uso por aqui... então, vamos ao que interessa!

Plataforma: Beecrowd (antiga URI)

Problema2567

Enunciado:

A secretaria de saúde pública da Nlogônia acabou de emitir um alerta. Um vírus está contagiando toda a população.

Após muitos estudos, os pesquisadores do país determinaram que, após infiltrarem o corpo hospedeiro, os virus se juntam dois a dois para tornarem-se letais. O nível de letalidade de uma infecção é determinado pela soma da diferença da idade, em dias, dos vírus pareados. Os vírus sem pares não influenciam no nível.

Desta forma, se existem 4 vírus no corpo hospedeiro com idades (em dias), iguais a

4, 10, 9, 43

E eles se paream da seguinte forma:

4 com 9, 43 com 10

Então nível de letalidade seria (9 - 4) + (43 - 10) = 38.

A secretaria de saúde pública da Nlogônia pediu para que você escrevesse um programa que, dado a contagem de vírus em um corpo e a idade de cada um deles, calcule o nível máximo de letalide que a infecção pode assumir.

Linguagens: C, C++ e Haskell

Solução:

Nesse exercício, portanto, bastava unir os valores dois a dois, sempre o maior com o menor e assim por diante, subtraindo e acumulando a resposta. É muito fácil! Pra isso, resolvi com ordenação, mas há outras formas de resolver. E você, como fez? Veja na sequência os três códigos disponíveis em C, C++ e Haskell.

Código em C++:

Aqui eu acabei usando uma estrutura vector para armazenar os valores e depois ordenei esses valores da estrutura com a função pronta sort, da biblioteca algorithm. Após essa ordenação, casei os valores inicial e final, depois o segundo e o penúltimo, e assim por diante, para fazer a subtração desejada no exercício, acumulando esses resultados e obtendo assim a resposta final.

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main () {
   int n;
   while (cin >> n) {
      vector<int> valores;
      int v;
      for (int i = 0; i < n; i++) {
         cin >> v;
         valores.push_back(v);
      }
      sort(valores.begin(), valores.end());
      int metade = n / 2;
      int resposta = 0;
      for (int i = 0; i < metade; i++ )
         resposta += valores.at(n-i-1) - valores.at(i);
      cout << resposta << endl;
   }
   return 0;
}

Código em C:

Aqui eu usei a função pronta qsort, de stdlib.h, e só criei a função compara para dizer como deve ser a comparação entre os valores. Isso porque após ordenar, basta unir sempre os pares do primeiro com o último, o segundo com o penúltimo e assim por diante.

#include <stdio.h>
#include <stdlib.h>
int compara(const void *a, const void *b) {
   return (*(int*)a - *(int*)b);
}

int main () {
   int n;
   while (scanf("%d", &n) != EOF) {
      int valores[n];
      for (int i = 0; i < n; i++)
         scanf("%d", &valores[i]);
      qsort(valores, n, sizeof(int), compara);
      int metade = n / 2;
      int resposta = 0;
      for (int i = 0; i < metade; i++ )
         resposta += valores[n-i-1] - valores[i];
      printf("%d\n", resposta);
   }
   return 0;
}

Código em Haskell:

A lógica adotada no código Haskell foi a mesma. Aqui também há função pronta para ordenação, bem como há função pronta para obter o primeiro valor de uma lista (init) como o último valor (last), o que facilita nessa junção de valores.

import Data.List (sort)
import System.IO (isEOF)

obtemResposta :: [Int] -> Int
obtemResposta [] = 0
obtemResposta (x:[]) = 0
obtemResposta (x:xs) = last xs - x + obtemResposta (init xs)

main :: IO ()
main = do
   concluido <- isEOF
   if concluido
      then return ()
      else do
         n <- readLn :: IO Int
         linha <- getLine
         let valores = map read (words linha) :: [Int]
         let valoresOrdenados = sort valores
         let resposta = obtemResposta valoresOrdenados
         print resposta
         main

Apoie o blog colaborando com qualquer quantia. A chave pix (chave aleatória) é 6d8bc7a8-5d74-493a-ab7a-3515baf35956

Obrigado!

URI (BEECROWD) - 2451 - PacMan - Ad-Hoc - C e C++

Vamos a mais uma solução por aqui!? Dessa vez o problema "PacMan", da categoria Ad-hoc. É um problema que vale poucos pontos, mas que apresenta uma solução interessante por manipular strings. Vamos ver como se resolve, na sequência desse post.

Plataforma: Beecrowd (antiga URI)

Problema2451

Enunciado:

Pacman é um jogo muito conhecido, onde o personagem tenta comer a maior quantidade possível de bolinhas, tendo ao mesmo tempo que fugir de vários fantasmas. Dessa vez, nosso personagem quer carregar a comida coletada para casa, mas o encontro com um fantasma, ao invés de terminar o jogo, faz com que toda a comida coletada seja roubada.

Neste problema os fantasmas não se movem, e o jogador sempre faz o Pacman percorrer o seguinte caminho:

O Pacman começa no canto superior esquerdo do tabuleiro.
O Pacman percorre toda a linha, da esquerda para direita, até chegar ao lado direito do tabuleiro.
O jogador desce uma posição, e percorre toda a linha, desta vez da direita para a esquerda.
As etapas 2 e 3 se repetem até que todo o tabuleiro tenha sido percorrido.
Infelizmente, Pacman não pode ignorar os comandos do usuário para fugir dos fantasmas ou pegar mais comida, mas ele pode, a qualquer momento, se aproveitar de um bug de implementação e interromper o jogo, levando consigo toda a comida que estiver carregando.

Você deve escrever um programa que determine a maior quantidade de comida que o Pacman pode levar, se escolher a melhor hora possível para sair. Note que o jogador também tem a opção de não sair antes do final do jogo.

Linguagens: C e C++

Solução:

Nesta solução, a proposta foi basicamente ler todas as linhas na ordem natural. Para isso, as linhas ímpares (considerando que se começa em uma linha par -- zero) foram invertidas. Isso facilita a busca para depois não precisar calcular os índices de forma diferente entre linhas pares e ímpares. Assim, basta percorrer o tabuleiro do jogo normalmente, na ordem natural, e procurar pelas maiores sequências de "o" até que um "A" seja encontrado. A maior sequência deve ser sempre armazenada (max) e comparada com a sequência atual (variável "atual"), que, se for maior, é atribuída à variável max também, bem como é zerada após esta ação para que se comece uma nova sequência a partir da posição atual no tabuleiro.

As soluções em C e C++ seguem a mesma lógica, mas você pode analisar as funções de reversão de string, que são diferentes. Em C++ eu aproveitei uma função já existente, reverse(). Em C eu mesmo implementei, para dar um toque especial e diferenciar as soluções .:)

Código em C++:

#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

int main () {
   int n, max = 0, atual = 0;
   string str;
   cin >> n;

   for (int i = 0; i < n; i++) {
      cin >> str;
      if (i & 1)
         reverse(str.begin(), str.end()); 

      for (int j = 0; j < n; j++) {
         if (str.at(j) == 'A') {
            if (atual > max)
               max = atual;
            atual = 0;
         }
         else if (str.at(j) == 'o')
            atual++;
      }
   }
   if (atual > max)
      cout << atual << endl;
   else
      cout << max << endl;

   return 0;
}


Código em C:


#include <stdio.h>

void reverteString (char *str, int n) {
    int i, temp;
    for (i = 0; i < n / 2; i++) {  
        temp = str[i];  
        str[i] = str[n - i - 1];  
        str[n - i - 1] = temp;  
    }  
}  

int main () {
   int n, max = 0, atual = 0, i, j;
   scanf("%d", &n);
   char str[n+1];
   for (i = 0; i < n; i++) {
      scanf("%s", str);
      if (i & 1)
         reverteString(str, n);
      for (j = 0; j < n; j++) {
         if (str[j] == 'A') {
            if (atual > max)
	       max = atual;
            atual = 0;
	 }
	 else if (str[j] == 'o')
         atual++;
      }
   }
   if (atual > max)
      printf("%d\n", atual);
   else
      printf("%d\n", max);

   return 0;

}

Novamente, segue os dados para apoio:

Chave aleatória (PIX) para doações: 6d8bc7a8-5d74-493a-ab7a-3515baf35956
Ajude-nos a manter o blog!

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