Advertisement
MayconAlves

1549 - Dividindo a Coca

Apr 25th, 2019
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.63 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define pb push_back
  4. #define rep(i,a,b) for( int i = a; i < b; i++ )
  5. #define debug(a) cout << #a << " = " << a << endl;
  6. #define debug2(a,b) cout << #a << " = " << a << " --- " << #b << " = " << b << endl;
  7. #define F first
  8. #define S second
  9.  
  10. using namespace std;
  11.  
  12. typedef long long int ll;
  13. typedef pair<int, int> ii;
  14.  
  15. // Forma mais segura e simples de se obter o valor de PI
  16. // Arco cujo cosseno é -1, ou seja pi radianos
  17. const double pi = acos(-1);
  18.  
  19. /*
  20. *   Para resolvermos o problema de dividir a coca, podemos usar duas abordagens
  21. *   - Solução matemática - funciona, mas talvez você gaste um bom tempo para chegar na forma final
  22. *   - Matemática simples + busca binária - Geralmente é o ideal, pois existe menos chance de obtermos problemas de precisão
  23. *     além de que provavelmente chegarimos a uma solução mais rapidamente - lembrem-se que na maratona cada minuto conta
  24. *
  25. *   Para usarmos a busca bibária vamos adotar o seguinte:
  26. *   - o código "chuta" qual o valor da altura de coca que teremos em cada copo
  27. *   - com a altura podemos calcular o volume presente no copo, e:
  28. *       - se p/ ter esse volume em cada copo eu preciso de mais coca do que eu disponho, devemos diminuir a altura e com isso o volume
  29. *       - caso contrário, podemos colocar um pouco mais de coca em cada copo aumentando a altura
  30. *   - ao fim da busca, teremos o valor de h com a precisão estipulada pela busca
  31. *
  32. *   Dado um valor h, podemos usar a formula do volume do tronco de cone para calcular o valor
  33. *                   Volume = pi/3 * (R*R+R*r+r*r) * h
  34. *   Onde:
  35. *   R: o raio da maior circulo do tronco
  36. *   r: o raio do menor circulo o tronco
  37. *   h: a altura do tronco
  38. *   Note que, o valor de R varia de aacordo com o valor de h, ou seja, devemos estipular o valor de h com a busca binária
  39. *   e cacular o valor de R para aquela atura, já o valor de r será o mesmo para qualquer altura
  40. *
  41. *   Para maior clareza, considere h como a altura total do copo e h' como a altura estipulada pela busca binária, respectivamente teremos
  42. *   R como o raio do circulo na altura h e R' como raio do circulo na altura h'
  43. *
  44. *   h     C    B             |      Observe o desenho ao lado e o imagine como uma planificação da vista frontal do copo
  45. *          \                |       Podemos notar que o triângulo ABC é semelhante ao triângulo ADE, logo, pode se perceber
  46. *   h'      E  D           |        que a relação BC/AB = DE/AD é satisfeita, sabemos que AB = h e AD = h', sabemos também que
  47. *            \            |         BC pode ser escrito como R - r, e DE como R'-r, logo isolando o valor de R', temos:
  48. *             \          |                  R' = (R-r)*h'/h;
  49. *              A________|
  50. *          
  51. *  
  52. */
  53.  
  54. int main(){
  55.    
  56.     int t, n;
  57.     double r, R, h, V;
  58.    
  59.     cin >> t;
  60.     while(t--){
  61.         cin >> n >> V;
  62.         cin >> r >> R >> h;
  63.        
  64.         // lo -> limite inferior da busca
  65.         // hi -> limite superior da busca
  66.         // hl -> altura que a busca binára "chutou" - h'
  67.         double lo = 0, hi = h, hl;
  68.        
  69.         // Para buscas binárias com valores reais, o mais comum é estipular uma precisão,
  70.         // nesse caso 1e-9 = 0.000000001, que é mais do que o suficiente para o problema
  71.         // A busca só para quando esa precisão for atendida, ou seja, quando a diferença entre o maior e
  72.         // o menor valor forem menores que 1e-9
  73.         while(hi-lo > 1e-9){
  74.             hl = (hi+lo)/2;
  75.             double Rl = (R-r)*hl/h + r;  // Calcula R'
  76.             double volume = pi/3 * h * (Rl*Rl + Rl*r + r*r);
  77.             // verifica se aquele volume é o suficiente para N pessoas
  78.             // Se sim, aumenta a altura, se não, diminui a mesma      
  79.             if(volume*n > V) hi = hl;
  80.             else lo = hl;
  81.         }
  82.         cout << fixed << setprecision(2) << hl << endl;
  83.     }
  84. }
  85. /*
  86. 2
  87. 1 200
  88. 5 6 8
  89. 2 350
  90. 3 3 16
  91. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement