Mostrando postagens com marcador problema fácil. Mostrar todas as postagens
Mostrando postagens com marcador problema fácil. Mostrar todas as postagens

domingo, 31 de julho de 2016

GUARDCOS - Guarda costeira

Olá meus amigos nerds! Hoje nós vamos ajudar a guarda costeira a pegar um ladrão de bolsas, já que é isso que o problema GUARDCOS - Guarda costeira pede para fazer. Mais especificamente, dadas as velocidades dos barcos da guarda costeira e do ladão determinar se ele será pego.

Solução

Esse é um problema bem fácil. Como o barco do bandido se desloca perpendicularmente a costa, em direção ao limite que a guarda costeira pode prende-lo, os guardas podem simplesmente chegar lá primeiro e prender o bandido. Assim basta saber se a guarda chega nesse ponto antes do bandido ou não.

A distância que o barco da guarda costeira percorre (hipotenusa do triângulo) pode ser calculada com o teorema de Pitágoras. Como a velocidade dos barcos é constante e conhecida temos:

Se tempo_guarda < tempo_bandido responda sim, ou seja

dist_guarda = sqrt(12^2 + d^2)
velocidade = distância / tempo => tempo = distancia / velocidade
dist_guarda/v_guarda < 12/v_bandido
dist_guarda * v_bandido < 12*v_guarda

Implementação

 



quinta-feira, 26 de maio de 2016

PECA7 - Peça Perdida

Olá meus amigos nerds! Hoje nós vamos ajudar Joãozinho a descobrir qual peça de seu quebra cabeça está faltando, já que é isso que o problema PECA7 - Peça Perdida pede para fazer. Mais especificamente, dadas n - 1 peças do quebra cabeça, numeradas de 1 a N, determinar a peça faltante.

Solução


A numeração das peças do quebra cabeça forma uma progressão aritmética, de primeiro termo 1, último termo N e razão 1. Assim, a soma de todas as numerações é N * (1 + N) / 2.

Por outro lado podemos somar as numerações das N-1 peças dadas. E se da soma total subtrairmos esse valor encontraremos o valor da peça faltante.

Implementação

 

Go, go, go :)


quinta-feira, 19 de maio de 2016

TRANSP11 - Transporte

Olá meus amigos nerds! Hoje vos  escrevo humildemente do México, infelizmente trabalhando, mesmo assim vamos brincar um pouco de resolver um probleminha fácil. Hoje vamos calcular o número de contêineres que um navio de carga suporta, já que é isso que o problema TRANSP11 - Transporte pede para fazer. Mais especificamente, dadas as dimensões do navio e dos contêineres calcular qual é o número máximo deles que podem ser acomodados no navio.

Solução


A solução do problema é bem simples. Como não podemos mudar a posição dos contêineres o máximo que podemos acomodar em uma direção é a medida do navio naquela direção dividida pelo tamanho correspondente de um contêiner. Assim basta multiplicar os valores obtidos para cada uma das três dimensões que temos nosso número máximo de contêineres.

Implementação

 

Mais um pouco de Go ai :)


quarta-feira, 4 de maio de 2016

MERCADO - Mercado do seu João

Olá meus amigos nerds! Depois de uma longa pausa, estou de volta a ativa. Hoje vamos brincar de arredondar o troco, já que é isso que o problema MERCADO - Mercado do seu João pede para fazer. Mais especificamente, dada uma lista contendo os valores das vendas determinar o total vendido, bem como a diferença entre esse total e o total arredondando-se o valor das vendas.

A solução desse problema foi um pedido do nosso leitor Henryque Santos.

Solução


A solução do problema é bem simples. Basta ir somando os valores das compras e somando o valor arredondado em uma outra variável (aplicando o critério de arredondamento do seu João). No final é só fazer a diferença dos dois valores.

Implementação

 

Resolvi estudar um pouco de Go para ver se é uma boa linguagem, então vocês vão começar a ver um pouco de Go por aqui :)


domingo, 28 de fevereiro de 2016

TESOUR11 - Caça ao tesouro

Olá meus amigos nerds! Hoje vamos brincar de caça ao tesouro, já que é isso que o problema TESOUR11 - Caça ao tesouro pede para fazer. Mais especificamente, dado um mapa com pistas da localização do tesouro, verificar se é possível encontrá-lo.

Solução


A bem da verdade o problema mais parece com um jogo de campo minado do que com uma caça ao tesouro.

Pense em cada pista como um conjunto de possíveis posições para o tesouro. Para que a posição do tesouro seja determinada de maneira única é necessário que a interseção desses conjuntos tenha tamanho 1. Assim, basta para cada pista calcular as possíveis posições do tesouro e fazer a interseção de todos os conjuntos.

Implementação




quarta-feira, 24 de fevereiro de 2016

2281. Rumo aos 9s

Olá meus amigos nerds! Hoje vamos relembrar um pouquinho de critérios de divisibilidade, já que é isso que o problema 2281. Rumo aos 9s pede para fazer. Mais especificamente, dado um número, queremos determinar se ele é divisível por nove.

Solução


O problema é bem simples, inclusive nos lembrando qual é o critério de divisibilidade por 9 (a soma dos dígitos o ser). Basta então implementar o critério dado.

Implementação


O único cuidado a ser tomado nesse problema é que o número inicial é potencialmente bem grande, tendo que ser manipulado como uma string.


terça-feira, 16 de fevereiro de 2016

LUA - Temperatura Lunar

Olá meus amigos nerds! Agora que já conseguiram "escutar" ondas gravitacionais vamos brincar de ajudar a NASA a determinar a temperatura média em uma certa região da Lua, já que é isso que o problema LUA - Temperatura Lunar pede para fazer. Mais especificamente, dada uma sequência de temperaturas determinar a maior temperatura média em um intervalo de tamanho m.

Solução


O problema é bem simples, basta ir iterando sobre a entrada e computando a temperatura média. É só lembrar que cada ponto do vetor é potencialmente um início para a janela de tamanho m da temperatura média.

Implementação




quarta-feira, 3 de fevereiro de 2016

TAPETE14 - Tapetes

Olá meus amigos nerds! Um dos objetivos desse blog é ser útil a quem está aprendendo, assim, hoje vamos resolver um problema a pedido por vocês.

Hoje vamos embalar tapetes, já que é isso que o problema TAPETE14 - Tapetes pede para fazer. Mais especificamente, queremos maximizar o valor da carga de tapetes dado que temos que transportar exatamente n tapetes que somam exatos l metros.

Solução


Olhando por cima esse problema parece o clássico problema da mochila, cada tenho uma mochila de tamanho n e quero enche-la com o máximo valor possível. Mas não é, uma vez que eu tenho a restrição de ter exatamente n objetos dentro dela. A solução para esse problema no entanto é mais simples.

Dado que o valor do tapete aumenta com o quadrado de seu comprimento é sempre melhor eu aumentar o tamanho de apenas um tapete, ou seja, embalar n-1 tapetes de tamanho 1 e um tapete de tamanho l - (n - 1) (correspondente ao comprimento restante da embalagem). Vou provar essa afirmação para n=2, mas ela é válida para qualquer n.

Sejam a e b os comprimentos dos dois tapetes que eu quero embalar. Logo:

a + b = l

Sendo que eu quero maximizar:

argmax(a^2 + b^2)
a < l (o tamanho de todos os tapetes tem que ser maior que 0)
b < l

mas a = l - b, logo:

argmax((l - b)^2 + b^2) = argmax(l^2 -2*l*b + 2*b^2)

l é uma constante. Como o coeficiente de b^2 é positivo o polinômio tem apenas um ponto de mínimo, ou seja, para maximiza-lo basta aumentar b. O maior valor possível de b é l - 1.

Assim para n qualquer teríamos a fórmula para o valor máximo = (l-n+1)^2 + (n - 1) [comprimento do maior tapete ao quadrado mais soma do valor dos n-1 tapetes de tamanho 1].

Implementação


Há um erro na indicação do tamanho da entrada. n, l <= 10^6 e não 106. Assim n^2 não cabe em 32 bits, logo temos que usar um inteiro de 64 bits (long long).


sábado, 30 de janeiro de 2016

11638. Maratona

Olá meus amigos nerds! Esses dias notei que parte dos leitores do blog são iniciantes, então decidi voltar a postar soluções de problemas mais fáceis, afinal não queremos assustá-los! Não é mesmo?

Hoje vamos ver se nossos amigos corredores conseguem terminar uma maratona, já que é isso que o problema 11638. Maratona pede para fazer. Mais especificamente, dada a distância máxima que um corredor consegue percorrer, sem tomar água e a posição dos pontos onde é possível conseguir água. Determinar se ele consegue terminar a prova.

Solução


Basta ir verificando se a distância entre dois pontos de água consecutivos não é maior que a distância que o corredor consegue percorrer sem se hidratar. Após o último ponto de água também é necessário ver se o corredor consegue chegar até o final da prova. Lembrando que uma maratona tem um percurso de 42195 metros.

Implementação



segunda-feira, 25 de janeiro de 2016

11013. Quadrado mágico

Olá meus amigos nerds! Hoje vamos brincar de escrever quadrados mágicos, já que é isso que o problema 11013. Quadrado mágico pede para fazer. Mais especificamente, dada uma matriz verificar se a soma de todas as suas linhas, colunas e diagonais é igual e que ela contém todos os números de 1 a n^2, sendo n a ordem da matriz.

Solução


Basta somar as linhas e colunas e ver se tem o mesmo resultado. Além disso, também é preciso verificar se todos os números de 1 a n^2 estão na matriz.

Implementação

Note que, dado o tamanho dos números da entrada, o resultado da soma pode não caber em um int.


quinta-feira, 14 de janeiro de 2016

8314. Fórmula 1

Olá meus amigos nerds! Hoje vamos descobrir quem ganhou o mundial de Formula 1, já que é isso que o problema 8314. Fórmula 1 pede para fazer. Mais especificamente, dadas as ordens de chegada dos pilotos em diversas corridas e o sistema de pontuação determinar quem foi o campeão ao fim da temporada.

Solução


Esse é um simples problema de ordenação. Some as pontuações de cada piloto ordene o resultado e imprima aqueles que tiverem mais pontos.

Implementação

Quando olho para um código feio como esse meu de muitos anos atráz fico feliz de ver que eu melhorei pelo menos um pouquinho :P


segunda-feira, 28 de dezembro de 2015

1850. Conte os Fatores

Olá meus amigos nerds! Hoje vamos brincar de fatoração, já que é isso que o problema 1850. Conte os Fatores pede. Mais especificamente, dado um número n, calcular o número de diferentes fatores primos que ele tem.

Solução


Esse é um problema fácil, bom para resolver depois da ressaca de Natal. Um algoritmo simples de fatoração é a solução.

Implementação



sexta-feira, 18 de dezembro de 2015

11675. Olimpíadas

Olá meus amigos nerds! Hoje vamos falar de olimpíadas, já que o problema 11675. Olimpíadas trata, justamente, disso. Nossa tarefa é, dada a informação dos países que receberam medalhas, gerar a classificação dos países na competição. Nesta tarefa, os países serão identificados por números inteiros. O melhor colocado deve ser o país que conseguiu o maior número de medalhas overall. Se houver empate entre dois países, o melhor classificado é o que tem o menor número de identificação.

Solução


Esse problema é quase uma cópia do 11646 Olimpíadas. Um problema simples de ordenação. Basta ordenar os países de acordo com a regra dada e pronto. 

Implementação


Para tornar o problema mais interessante, implementei eu mesmo o quicksort. No outro post eu expliquei um pouco de como é a implementação dele.


domingo, 29 de novembro de 2015

3742. Feynman

Olá meus amigos nerds. Hoje vamos resolver um probleminha de matemática, já que é isso que o problema 3742. Feynman pede para fazer. Mais especificamente, quantos quadrados diferentes existem em um quadriculado de N x N quadrados?

Solução


Para responder essa pergunta basta somar quantos quadrados de 1, 2, ..., N existem no quadriculado.

Para descrever um quadrado em um quadriculado é preciso apenas de um ponto: o ponto de início do quadrado, a partir desse ponto todos os outros quadradinhos do quadriculado que o quadrado ocupa ficam determinados.

Dito isso, como o quadriculado tem N x N existem N^2 quadrados de tamanho 1.

Posso começar um quadrado de tamanho 2 em qualquer uma das N linhas e N colunas com excessão da última linha e coluna. Assim existem (N-1)*(N-1) = (N-1)^2 quadrados de tamanho 2.

Já quadrados de tamanho 3 não podem começar nas duas últimas linhas e colunas. Assim teríamos (N-2)*(N-2)=(N-2)^2 quadradinhos de tamanho 3.

...

Por fim existe apenas 1 quadrado de tamanho N.

Em outras palavras:

1 -> N^2
2 -> (N-1)^2
3 -> (N-2)^2
...
N -> 1

Então a resposta é a soma dos quadrados dos números de 1 a N.

Implementação




quarta-feira, 14 de outubro de 2015

2608. Duende Perdido

Olá meus amigos nerds. Hoje vamos ajudar um duende a escapar de um complexo de cavernas. Já que é isso que o problema 2608. Duende Perdido nos pede para fazer. Mais especificamente, dado o mapa de um complexo de cavernas, onde estão marcadas as saídas e salões onde o duende não pode visitar, determinar o menor número de salões que o duende tem que passar para poder atingir uma das saídas.

Solução


Podemos resolver esse problema facilmente, se pensarmos nos salões que o duende pode entrar como sendo vértices de um grafo, de modo que os caminhos entre eles sejam as arestas. Assim, a solução do problema seria, simplesmente, computar o caminho mínimo entre a posição atual do duende e uma das saídas. Poderíamos computar o caminho mínimo usando o algoritmo de dijkstra, mas como o tamanho da entrada do problema é pequeno, uma busca em largura é suficiente.

Implementação




quarta-feira, 7 de outubro de 2015

8709. Fusões

Olá meus amigos nerds. Hoje vamos verificar se dois códigos bancários pertencem a um mesmo banco ou não. Já que é isso que o problema 8709. Fusões nos pede para fazer. Mais especificamente, dados uma lista de bancos e uma série de fusões entre dois bancos, responder se dois bancos (identificados por seus códigos bancários) são o mesmo banco ou não.

Solução


Esse é um problema fácil. Já resolvemos alguns problemas bem parecidos aqui no blog. O único desafio aqui é fazer união de conjuntos de modo eficiente. Isso pode ser feito usando uma dijoint set forest que implementa tanto a operação de union quanto de find de forma eficiente (O(1)).

Implementação




quarta-feira, 23 de setembro de 2015

1332. Dengue

Olá meus amigos nerds. Hoje vamos ajudar o povo da Costa do Mosquito a instalar um posto de vacinação. Já que é isso que o problema 1332. Dengue nos pede para fazer. Mais especificamente, dado um conjunto de cidades e as rotas que as ligam, determinar em qual cidade deve ser instalado o posto de vacinação de modo a minimizar a distância percorrida por quem mora mais longe do posto.

Solução


Esse problema implora que usemos grafos para modela-lo. As cidades são os vértices e as rodovias as arestas. Como a entrada do problema é bem pequena, basta então calcular a distância entre todas as cidades e escolher a cidade que tem a menor distância máxima. Para calcular a distância de uma cidade para todas as outras podemos usar o algoritmo de dijkstra. Facinho né!

Implementação




quarta-feira, 2 de setembro de 2015

18552. Famílias de Troia

Olá meus amigos nerds. Hoje vamos brincar com árvores genealógicas para tentar descobrir quantas famílias sobreviveram a guerra de Tróia. Já que é isso que o problema 18552. Famílias de Troia nos pede para fazer. Mais especificamente, dadas as relações de parentesco entre os sobreviventes da guerra de Tróia, determinar quantas famílias sobreviveram.

Solução


Aqui vale um disclaimer, quando eu resolvi esse problema a descrição da entrada estava errada. A primeira linha contem dois inteiros n (número de sobreviventes e m (total de relações entre famílias). Siga o formato dos exemplos que ele está certo.

Uma abordagem modelando o problema com grafos e aplicando uma busca em profundidade (ou largura) resolveria esse problema. Mas eu quero dar uma solução um pouco mais eficiente e simples.

Pense nas famílias como conjuntos, comece com cada sobrevivente como pertencente a um conjunto (formado apenas por ele), quando descobrimos que dois sobreviventes pertencem a uma mesma família faça a união dos conjuntos que esses sobreviventes pertencem. A solução para o problema será o número de conjutos existente ao final. Simples não!? O problema agora é só de como representar os conjuntos de forma que operações de união e pertinência sejam executadas de modo eficiente. Mas isso é justamente o que um dijoint forest set faz, então o problema se torna trivial.

Implementação




Note o uso que fiz dos argumentos de um template para parametrizar o tamanho máximo dos vetores que compõe a classe dsf.

domingo, 23 de agosto de 2015

19949. Fechadura

Olá meus amigos nerds. Hoje vamos brincar de abrir fechaduras. Já que é isso que o problema 19949. Fechadura nos pede para fazer. Mais especificamente, dados uma serie de números (que representam a altura dos pinos da fechadura) e uma posição em que os pinos tem que ser colocados para que a fechadura se abra, determinar qual o número mínimo de movimentos de elevar ou abaixar os pinos para que a fechadura se abra.

Solução


Quando li esse problema pela primeira vez, achei que sua solução envolveria programação dinâmica, já que ele pedia o menor número de movimentos. Entretanto se observarmos bem, o problema afirma que quando um pino é mexido o da frente também o é. Assim, não há o que otimizar, basta percorrer o vetor com as alturas (armazenando o número de movimentos gastos para mover o pino anterior) e ir somando o número de movimentos necessários.

Seja 'altura' o vetor com as alturas dos pinos
Seja m a altura que devemos colocar os pinos
soma_mov = 0
acum = 0
for altura in alturas
        diff = m - (altura + acum)
        soma_mov += abs(diff)
        acum = diff

Implementação




quarta-feira, 12 de agosto de 2015

19958. Detectando Colisões

Olá meus amigos nerds. Hoje vamos fazer um algoritmo para detectar se dois retângulos se interceptam ou não. Já que é isso que o problema 19958. Detectando Colisões nos pede para fazer. Mais especificamente, dados dois retângulos, que tem seus lados paralelos aos eixos, determinar se há alguma interseção entre eles.

Solução


O caso geral desse problema, que é determinar se dois polígonos tem pontos de interseção é bem complexo. Para nos ajudar, o problema trata apenas de retângulos e ainda fixa que seus lados são paralelos aos eixos. Ai fica fácil né!

O problema nos fornece os cantos inferior esquerdo e superior direito de cada retângulo. Vamos tentar estabelecer as condições para que os dois retângulos não possam se interceptar.

Caso o canto superior direito de um dos retângulos esteja 'atráz' do canto inferior esquerdo do outro não há como haver interseção pois nesse caso um retângulo 'termina' antes que o outro comece. Da mesma forma, se o canto superior direito de um dos retângulos estiver 'abaixo' do canto inferior esquerdo do outro um dos retângulos terá 'terminado' antes do outro começar. Pensando nas coordenadas x,y desses pontos teríamos (sendo a e b os retângulos):

if (a_sup_dir_x < b_inf_esq_x ||
     a_sup_dir_y < b_inf_esq_y ||
     b_sup_dir_x < a_inf_esq_x ||
     b_sup_dir_y < a_inf_esq_y )
        responda não

A condição acima é necessária. Agora vou mostrar que ela é suficiente. Observe que na situação dos dois cantos superiores da direita estarem no sub espaço acima e a direita dos cantos inferiores, os seguimentos  (a_inf_esq, a_sup_dir) e (b_inf_esq, b_sup_dir) seriam tanto diagonais do retângulo formado pelos pontos (a_inf_esq, b_sup_dir, a_sup_dir, b_inf_esq) quanto dos retângulos originais, mas como as diagonais de um retângulo sempre se interseptam, resulta que esse ponto pertencerá a uma diagonal de cada um dos retângulos a e b e assim eles também se interceptam.

Implementação