[수치 해석][이분법] RATIO 승률 올리기
2021. 1. 22. 20:05ㆍ카테고리 없음
1. 이분법
이 문제는 간단히 수학식으로 표현할 수 있다.
Z = M*100 / N
Zx = (M+x) * 100 / (N+x)
Z < Zx
이식을 조건으로 하는 이분법을 사용하면
Z < Zx<= Z+1
가 되는 x값을 구할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
long long T, N, M, Z;
int bi()
{
long long lo = -1ll, hi = 2000000001ll;
for(;lo + 1 < hi;)
{
long long mid = (lo+hi)/2ll;
if((M*100/N) < 100*(M+mid)/(N+mid)) hi = mid;
else lo = mid;
}
if(hi == 2000000001ll) hi = -1;
return hi;
}
int main()
{
std::cin>>T;
for(int i = 0; i < T; i++)
{
std::cin>>N>>M;
std::cout<<bi()<<"\n";
}
}
|
cs |
2. 수학적 해법
Z = M*100 / N
Zx = (M+x) * 100 / (N+x)
Z < Zx<= Z+1 이 되는 Zx는 최저 Z+1이다.
R = Z+1 이라 하자
Zx >= R
(M+x) * 100 >= (N+x)*R
x에 대해 정리하면
(100 - R)x >= RN - 100M
x >= (RN - 100M) / (100 - R)
x는 정수이므로 오른쪽 분수에 올림하면
최저 x를 구할 수 있다.
1
2
3
4
5
6
|
long long foo()
{
long long R = (M*100/N) + 1;
if(N==M ||R == 100)return -1;
return (long long)ceil((long double)(R*N-100*M)/(100-R));
}
|
cs |