
O problema consiste em, dadas as alturas A e B das extremidades das retas, determinar quantas intersecções ocorrem. Para simplificar, é garantido que nenhum par de segmentos começa ou termina na mesma altura e que nunca ocorre de mais de dois segmentos cruzarem no mesmo ponto.
A quantidade de segmentos nos arquivos de teste é baixa: máximo de 2 no small input e 1000 no large input. Isto significa que, se o teste da intersecção de duas retas for rápido, dá para analisar todos os pares (serão no máximo 1 milhão de pares a testar).
Uma primeira observação importante é que a distância entre os dois prédios não é dada; o resultado independe dela. Vamos considerar que a coordenada horizontal do prédio da esquerda é zero e a do prédio da direita é 1. Usando a tradicional equação da reta (Y = aX + b) podemos calcular a coordenada horizontal da intersecção do segmento de (0, Ai) a (1, Bi) com o segmento de (0, Aj) a (1, Bj):
1o segmento: Y = Ai + (Bi-Ai) * X
2o segmento: Y = Aj + (Bj-Aj) * X
na intersecção o Y é igual para os dois segmentos logo:
Ai + (Bi-Ai) * X = Aj + (Bj-Aj) * X
resolvendo esta equação para X, obtemos
X = (Aj - Ai) / (Bi - Ai - Bj + Aj)
Se (Bi - Ai - Bj + Aj) for zero, não teremos intersecção (os segmentos são paralelos). Para termos uma intersecção entre os prédios, X precisa estar entre 0 e 1 (pelo enunciado não pode ser exatamente 0 ou 1). Resta notar que não precisamos calcular a divisão ou trabalhar com números fracionários:
- Se o sinal de (Aj - Ai) for diferente do de (Bi - Ai - Bj + Aj), o resultado será menor que 0.
- Se os sinais forem iguais e |Aj - Ai| for maior que |Bi - Ai - Bj + Aj| o resultado será maior que 1.
- //
- // Google CodeJam 2010 - Round 1C, Problem A
- // DQuadros
- //
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- int a[1000], b[1000];
- int N;
- void main (void)
- {
- int iCase, nCases;
- int i, j, ni;
- int da, db;
- scanf ("%d\n", &nCases);
- for (iCase = 1; iCase <= nCases; iCase++)
- {
- scanf ("%d\n", &N);
- for (i = 0; i < N; i++)
- scanf ("%d %d\n", &a[i], &b[i]);
- ni = 0;
- for (i = 0; i < N; i++)
- {
- for (j = i; j < N; j++)
- {
- da = a[j] - a[i];
- db = b[i]-a[i]-b[j]+a[j];
- if (db != 0)
- {
- if (da > 0)
- {
- if (db > da)
- ni++;
- }
- else
- {
- if (-db > -da)
- ni++;
- }
- }
- }
- }
- printf ("Case #%d: %d\n", iCase, ni);
- }
- }
Nenhum comentário:
Postar um comentário