[수치 해석][이분법] 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==||== 100)return -1;
    return (long long)ceil((long double)(R*N-100*M)/(100-R));
}
cs

RATIO