자성체 N개가 주어질 때 자성체 사이사이의 균형점을 구해서 출력하는 문제다.


F = G*m1*m2/(d*d)라고 되어있는데 아무곳에서 자성체 하나를 놓고 계산을 해보면


G와 물체의 질량은 계산식에 전혀 영향을 미치지 못하는 것을 알 수 있다.


이 문제에서는 이분탐색을 사용할 것이다.


현재 균형점이라 생각할 지점에서 왼쪽 자성체들에게 받는 힘을 더하고


오른쪽 자성체들에게 받는 힘을 뺐을 때 0이 된다면 그곳은 균형점일 것이다.


하지만 소수점 계산이라 정확한 0이 나오기는 힘들고 입력값의 범위도 주어져 있지 않으므로 그냥 int범위로 생각하고 풀자.


int가 대충 1e9정도이므로 이것을 토대로 계산했을 때 오차가 1e-9 미만이어야 한다는 것은 계산 범위가 1e18과 같다는 것이므로


루프를 60번은 돌아야 한다.(50번 돌아도 통과하더라. 간혹 input의 범위가 불분명한 문제가 있어 난감하다)


i번째 자성체의 위치를 l로잡고 i+1번째를 r로 잡은 후 그 사이에서 이분탐색을 한다.



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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <algorithm>
using namespace std;
 
typedef double db;
 
int t, n;
db x[10], m[10];
 
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cout << fixed;
    cout.precision(10);
    cin >> t;
    for (int tc = 1; tc <= t; ++tc) {
        cin >> n;
        for (int i = 0; i < n; ++i)
            cin >> x[i];
        for (int i = 0; i < n; ++i) 
            cin >> m[i];
        cout << "#" << tc << " ";
        for (int i = 0; i < n - 1++i) {
            db l = x[i], r = x[i + 1], ans = 0;
            for (int k = 0; k < 50++k) {
                db mid = (l + r) / 2;
                db s = 0;
                for (int j = 0; j <= i; ++j) 
                    s += m[j] / ((mid - x[j])*(mid - x[j]));
                for (int j = i + 1; j < n; ++j) 
                    s -= m[j] / ((mid - x[j])*(mid - x[j]));
                if (s > 0) {
                    l = mid;
                }
                else {
                    ans = mid;
                    r = mid;
                }
            }
            cout << ans << " ";
        }
        cout << '\n';
        //cout << "#" << tc << " " << ans << '\n';
    }
    return 0;
}
cs


'SWEA' 카테고리의 다른 글

5216. 다항식의 계수  (0) 2018.09.04
1244. 최대 상금  (0) 2018.08.29
1247. 최적 경로  (0) 2018.08.29
1251. 하나로  (0) 2018.08.29
2105. 디저트 카페  (0) 2018.08.29

+ Recent posts