※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 14919번 문제인 분포표 만들기이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/14919
14919번: 분포표 만들기
0과 1사이의 실수 a1, a2, ..., aN이 입력으로 주어졌다고 하자. 구간 [0,1)을 다음과 같이 m개의 길이 L=1/m인 부분구간으로 나누자. 각 구간은 순서대로 b1, b2, ..., bm이다. b1: 0 ≤ x < L, b2: L ≤ x < 2L, ..
www.acmicpc.net
주어지는 소수들은 소수점 여섯자리까지만 주어지고 모두 0보다 크며 1보다 작으므로, "0." 이후의 소수점 첫째자리부터 여섯째자리까지의 수를 정수 X로 읽어 소수 대신 이용하는 것으로 실수오차를 회피할 수 있다.
X/1000000 < K/M 인지 실수연산 없이 비교하기 위해 양변에 M * 1000000을 곱하면, X * M < K * 1000000와 같은 동치인 관계식을 얻을 수 있다. 이 식을 이용해 X를 순서대로 정렬하여 스위핑을 이용해 문제를 해결하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;
ll M;
ll arr[1000000];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> M;
int N = 0;
string s;
while (cin >> s) {
while ((int)s.length() < 8) s += '0';
arr[N++] = stoll(s.substr(2, 6));
}
sort(arr, arr + N);
int cnt = 0;
ll idx = 1;
for (int i = 0; i < N; i++) {
if (arr[i] * M < 1000000LL * idx) cnt++;
else {
cout << cnt << ' ';
cnt = 0;
idx++;
i--;
}
}
while (idx <= M) {
cout << cnt << ' ';
cnt = 0;
idx++;
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 24981 // C++] Counting Liars (0) | 2022.04.26 |
---|---|
[BOJ 24982 // C++] Alchemy (0) | 2022.04.25 |
[BOJ 14926 // C++] Not Equal (0) | 2022.04.24 |
[BOJ 14927 // C++] 전구 끄기 (0) | 2022.04.24 |
[BOJ 14924 // C++] 폰 노이만과 파리 (0) | 2022.04.24 |