Buenas!
Cá estou para apresentar mais um problema resolvido!
Foi resolvido agora o problema "Comunicação Espacial". Esse problema é relativamente novo na plataforma e não tem muitas soluções, pelo menos até agora. Eu, inclusive, ainda não o resolvi em outras linguagens, fiz ele só em Haskell por enquanto. Veja na sequência desse post como eu fiz para resolvê-lo!
Porém, como costumo indicar em alguns posts, recomendo que antes de resolver qualquer algoritmo do BEECROWD você siga os seguintes passos:
- Leia todo enunciado do problema.
- Leia os tópicos do fórum em caso de dúvidas. As vezes os outros usuários podem esclarecer questões interpretativas e fornecer casos de teste interessantes ou outras dicas valiosas.
- Prepare arquivos de entrada para teste, considerando as entradas de exemplo do Beecrowd, do udebug e outros valores limite;
- Prepare o ambiente de desenvolvimento e utilize os mesmos parâmetros dos compiladores do Beecrowd
- Prepare um código-fonte padrão, já contendo a chamada às bibliotecas padrão, pré-processadores, retorno de função e um comando de escrita com "\n", pois no Beecrowd a grande maioria dos problemas exige a quebra de linha final.
Plataforma: BEECROWD
Problema: 3162
Enunciado:
O ano é 2337. Milhares de naves de tripulações humanas viajam pelo espaço de forma alucinada para lá e para cá. E o melhor: as naves conseguem se comunicar através de rádio, é possível até mesmo que tripulações entre naves distintas jogarem truco.
No entanto, infelizmente a qualidade do sinal esvanece com a distância. Enquanto naves próximas conseguem se comunicar bem, as naves que estão distantes possuem péssima intensidade de sinal para se comunicar. Por esse motivo, as naves comunicam-se preferencialmente com a nave mais próxima.
Considerando um trecho do espaço onde as naves podem ser consideradas pontos no espaço, portanto com coordenadas tridimensionais, com cada eixo podendo ter valor entre 0 e 100 u.m. Sabe-se que a intensidade do sinal de comunicação se dá pela distância entre as naves; de modo que naves que distam entre si até 20 u.m. possuem uma intensidade alta; acima de 20 u.m. e até 50 u.m. possuem uma intensidade média; enquanto a intensidade do sinal acima de 50 u.m. é tão baixa que não possibilita a comunicação entre as naves.
Dadas as informações passadas, ajude os tripulantes destas naves a conseguirem saber a intensidade do sinal entre cada uma delas e a nave mais próxima, para informá-los se eles vão conseguir ter uma boa comunicação entre si.
Linguagem: Haskell
Solução:
A ideia é ler as coordenadas e salvá-las em listas de inteiros, o que é feito com a função replicate monádica. Depois disso, cria-se uma lista contendo a distância de cada ponto com os demais (ok, tive preguiça e calculei distâncias duplicadas, com certeza não precisava disso). O cálculo da distância em R3 é o mesmo que já aprendemos na matemática no ensino médio, é necessário somar o quadrado da diferença de cada eixo e tirar a raiz disso.
Depois, o que fiz foi ordenar as listas de distâncias e pegar sempre a segunda distância, pois a primeira será zero (distância de um ponto até ele mesmo). Ao pegar o segundo elemento de cada lista de distâncias, basta verificar se ele se enquadra em intensidade alta, baixa ou média com base em cada condição e imprime A, B ou M para cada caso.
Usei a função map monádica sem retorno (mapM_) para imprimir a resposta porque assim ela é fácil de usar e estou interessado somente no efeito que é produzido (escrita na tela), e não no resultado.
Eu mesmo cheguei a criar outras soluções para esse exercício, mas dessa vez vou deixar só essa aqui.
E aí, conseguiu entender?
Código em Haskell:
import Control.Monad (mapM_, replicateM)
import Data.List (sort)
getDistance :: [Double] -> [Double] -> Double
getDistance (x1:y1:z1:[]) (x2:y2:z2:[]) = sqrt ((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)
getAllDistances :: [[Double]] -> [Double] -> [Double]
getAllDistances [] _ = []
getAllDistances (l:ist) point = getDistance l point : getAllDistances ist point
getAns :: [Double] -> [Char]
getAns list
| list!!1 < 20 = "A"
| list!!1 <= 50 = "M"
| otherwise = "B"
main :: IO ()
main = do
n <- readLn
coord <- replicateM n (do
line <- getLine
let xyz = map read (words line) :: [Double]
return (xyz))
let values = map (getAllDistances coord) coord
let sorted = map sort values
let ans = map getAns sorted
mapM_ putStrLn ans
Ajude o blog a continuar postando respostas para ajudar a todos com exercícios de programação! A chave aleatória (PIX) para doações é 6d8bc7a8-5d74-493a-ab7a-3515baf35956.
Um abraço a todos!