Considere a seguinte pergunta da rodada 1C do Google Code Jam :
A Grande Muralha da China começa como uma linha infinita, onde a altura em todos os locais é .
Algum número de tribos , atacará a parede a parede de acordo com os seguintes parâmetros - um dia de início, , uma força de partida , uma coordenada oeste de início, e uma coordenada leste de início, . Este primeiro ataque ocorre no dia , no intervalo , a força . Se houver qualquer parte da Grande Muralha dentro de com altura , o ataque será bem-sucedido e, no final do dia, a parede será construída de modo que qualquer segmento dela dentro de de altura estaria então em alturaN ≤ 1,000 D S W E D [ W , E ] S [ W , E ] < S [ W , E ] < S S (ou maior, se algum outro ataque naquele dia atingir o mesmo segmento com força )
Cada tribo executará até ataques antes de recuar e cada ataque será determinado iterativamente do anterior. Toda tribo tem alguns , e que determinam sua sequência de ataques: eles esperarão dia entre os ataques, eles moverão seu alcance de ataque unidades para cada ataque (negativo = oeste, positivo = leste), embora o tamanho do alcance permaneça o mesmo e sua força também aumente / diminua em um valor constante após cada ataque.δ D δ X δ S δ D ≥ 1 δ X
O objetivo do problema é, dada uma descrição completa das tribos atacantes, determinar quantos de seus ataques serão bem-sucedidos.
Consegui codificar uma solução que funciona, executando em cerca de 20 segundos: acredito que a solução que implementei leva o tempo , em que o número total de ataques em uma simulação (máximo de ) e o número total de pontos de borda exclusivos nos intervalos de ataque (máximo de ).A = 1000000 X = 2000000
Em um nível alto, minha solução:
- Lê todas as informações da Tribo
- Calcula todas as coordenadas exclusivas para os intervalos de ataque -O ( A )
- Representa a parede como uma árvore binária atualizada preguiçosamente sobre os intervalos que rastreiam os valores mínimos de altura. Uma folha é a extensão de duas coordenadas sem nada no meio e todos os nós pais representam o intervalo contínuo coberto por seus filhos. -X O ( X log X )
- Gera todos os ataques que toda tribo executará e os classifica por dia -
- Para cada ataque, veja se seria bem-sucedido ( tempo de consulta). Quando o dia mudar, percorra todos os ataques bem-sucedidos não processados e atualize o mural de acordo ( hora de atualização para cada ataque). -log X O ( A log X )
Minha pergunta é a seguinte: Existe uma maneira de fazer melhor que ? Talvez haja alguma maneira estratégica de tirar proveito da natureza linear dos sucessivos ataques do Tribes? 20 segundos parecem muito longos para uma solução pretendida (embora o Java possa ser o culpado por isso).