Algoritmos - dannluciano/wiki GitHub Wiki
Busca binária em resposta
A busca binária tradicional é um algoritmo de pesquisa em vetores usando o paradigma divisão e conquista, para funcionar o vetor precisa estar ordenado (crescente ou decrescente), se você não conhece recomendo pesquisar sobre para entender melhor oque será explicado.
A busca binária em resposta consegue resolver problemas além de uma simples pesquisa, ela trabalha diretamente no valor do resultado, o algoritmo vai "chutando" até achar a resposta para o seu problema, um exemplo comum é achar a raiz quadrada de um número.
Vamos resolver o problema “Aggressive cows” para entender.
link do problema: AGGRCOW
Problema:
O fazendeiro John construiu um estábulo bem longo, com N (2 <= N <= 100,000) baias. As baias estão alocadas nas seguintes posições x1,...,xN (0 <= xi <= 1,000,000,000). As vacas dele C (2 <= C <= N) não gostam desse layout e ficaram agressivas uma com a outra quando colocadas em um estábulo. Para impedir que as vacas se machuquem, John quer atribuir as vacas às baias, de modo que a distância mínima entre duas delas seja a maior possível. Qual é a maior distância mínima?
Entrada
t - o número de casos de teste e, a seguir, t casos de teste.
- Linha 1: Dois números inteiros separados por espaço: N e C
- Linhas 2..N + 1: A linha i + 1 contém um local de paralisação inteiro, xi
Resultado
Para cada caso de teste, imprima um número inteiro: a maior distância mínima.
Caso de entrada:
1 5 3 1 2 8 4 9
Saida:
3 Abaixo está o código feito em c++ comentado.
#include <bits/stdc++.h>
using namespace std;
int main() {
int a;
cin >> a; //recebendo o número de casos de teste
for(int i = 0; i < a; i++){
int n, c;
cin >> n >> c; //recebendo N e C
int baias[n + 1];
for(int j = 1; j <= n; j++){
cin >> baias[j];
}
sort(baias + 1, baias + n); //ordenando as posições das baias
Até agora só coletei os dados da questão e ordenei as baias em ordem não decrescente, nada demais.
int left = 1;//left começa com 1 que é o valor mínimo de distância entre duas baias.
int right = baias[n];//right é inicializado com o valor da baia mais a direita.
Essas duas variáveis “left” e “right” serão o “raio” de busca, já que o menor valor possível de distância entre duas vacas tem que ser 1 e o máximo é a distância da última baia (poderia ser baias[n] - baias[1]), resumindo, a resposta está entre essas duas variáveis.
int fm = -1;
while(left <= right){
int meio = (left + right) / 2;//a variável “meio” vai chutar algum valor da metade de left + right
int dis = 0;//a variável "dis" vai fazer a contagem e a divisão das vacas
int longe = 1;//essa variável vai ser a responsável para dizer quantas vacas conseguiram bater a meta do “meio”
//a variável "j" começa com 2 pois a primeira vaca já foi colocada na primeira baia
for(int j = 2; j <= n; j++){
//vai verificar se a distância é maior ou igual ao valor pela variável "meio" para colocar uma vaca.
if(dis >= meio){
dis = 0;
longe++;
}
dis += baias[j] - baias[j - 1];
}
A variável “dis” calcula a distância da baia anterior até baia atual, caso seja possível ter uma vaca na baia atual, zera a distancia, se não, vai para a próxima baia.
//é preciso verificar se a última posição pode ser colocada mais uma vaca
if(dis >= meio){
dis = 0;
longe++;
}
//caso todas as vacas tenham sido colocadas a pelo menos ao que foi "chutado" pelo "meio", vamos tentar aumentar ainda mais a distância entre elas.
if(longe >= c){
left = meio + 1;
fm = meio;//guardei o valor do valor chutado pois é uma possivel melhor resposta
}else{
right = meio - 1;//o valor "chutado" foi muito alto, temos que tentar um valor menor
}
}
cout << fm << endl;//imprimindo a resposta
}
}
Obs: Preste atenção como está implementado a busca binária pois é fácil dar algum erro ou não entregar o resultado que foi proposto.
Referencias:
https://noic.com.br/materiais-informatica/curso/techniques-01/ https://www.topcoder.com/community/competitive-programming/tutorials/binary-search
Escrito por: Walex henrique
Lembrando que sou iniciante em programação.
Algumas questões para treino:
https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/ https://leetcode.com/problems/heaters/ https://leetcode.com/problems/sqrtx/
Tente usar busca binária em resposta.