BOJ/이분 탐색

[C/C++] 백준 - 2428번 : 표절

JWonK 2022. 5. 17. 16:48
728x90
반응형

https://www.acmicpc.net/problem/2428

 

2428번: 표절

첫째 줄에 제출한 솔루션의 개수 N이 주어진다. 둘째 줄에는 각 솔루션 파일의 크기 size(F1), size(F2), ..., size(FN)이 주어진다. (1 ≤ N ≤ 100,000, 1 ≤ size(Fi) ≤ 100,000,000) 솔루션 파일의 크기는 정수이

www.acmicpc.net

문제

세계적인 석유 재벌 "규현 조 압둘 티크리티 안드레스 후세인 리오넬 솔레르 살라 마리우 두스 산투스 펠리스 빈 자이드 술탄 친나왓 뱅거 7세"는 1등 상품으로 페라리를 걸고 프로그래밍 대회를 개최했다. 이 대회의 참석자는 총 N명이고 각각 솔루션 파일 1개를 제출했다. 이 솔루션 파일을 F1, F2, ..., Fn이라고 한다.

채점 결과를 발표하기 전에, 남의 것을 배낀 사람이 있는지 찾아내려고 한다. 이 대회의 주최측은 두 파일을 비교해서 너무 비슷한지 아닌지 판별하는 프로그램이 있다.

하지만, 제출한 파일의 개수가 너무 많아서, 모든 쌍을 검사한다면, 2012년 지구가 멸망할 때 까지도 검사를 해야할 판이다. 따라서, 파일 크기가 너무 다른 경우에는 그러한 쌍을 검사하지 않고 넘어가기로 했다.

좀더 정확하게 하기 위해서, 대회의 심판들은 두 파일이 있을 때, 작은 파일의 크기가 큰 파일 크기의 90%보다도 작을 때는, 이러한 쌍은 검사하지 않고 넘어가기로 했다. 따라서, (Fi, Fj) 쌍을 검사해야 하는데, 이때, i≠j이고, size(Fi) ≤ size(Fj)이면서, size(Fi) ≥ 0.9 × size(Fj)인 쌍만 검사하려고 한다.

몇 개의 쌍을 검사해야 하는 지 구하는 프로그램을 작성하시오.

 


 

모든 쌍을 검사하지 않고, 조건에 만족하는 쌍만 검사하기 때문에 조건에 만족하는 개수만 세어주면 된다.

그러면 조건에 만족하는 쌍을 어떻게 세야하는 것일까?

 

F_i로 올 수 있는 값들이 중복을 허용하기 때문에 만족하는 모든 수를 찾아야한다.

그렇다면 정렬을 우선 수행하여 수를 나열해주고 조건에 만족하는 최초의 값 위치만 파악해주면 되지 않을까?

 

여기서 하나 더 생각해야 할 점이 조건에 만족하는 값을 찾기 위해 0.9를 곱하지만 문제의 조건을 보면 주어지는 수들은 모두 정수이다. 그렇기 때문에 원하는 조건의 값을 구하기 위해 0.9를 곱하고 나면 실수가 되고 실수보다 큰 정수를 찾기 위해서는 소수점이 .0이 아닌 이상 모두 +1보다 큰 값의 위치를 찾아주어야 한다.

 

이 부분만 잘 적용하면 쉽게 해결 가능한 문제인 것 같다.

#include <iostream>
#include <algorithm>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)

using namespace std;

int N;
vector<int> file;

void input() {
	cin >> N;
	file = vector<int>(N, 0);
	for (int i = 0; i < N; i++) {
		cin >> file[i];
	}
}

int integerFile(double file) {
	if ((file - (int)file) == 0) return int(file);
	return int(file + 1.0);
}

ll solution() {
	ll answer = 0;
	sort(file.begin(), file.end());
	for (int i = file.size() - 1; i >= 0; i--) {
		int xFile = integerFile(file[i] * 0.9);
		int pos = lower_bound(file.begin(), file.end(), xFile) - file.begin();

		if (!pos) {
			if (file[pos] >= file[i] * 0.9) {
				answer += (i - pos);
			}
		}
		else {
			answer += (i - pos);
		}
	}
	return answer;
}

int main() {
	fastio;
	input();
	cout << solution() << endl;

	return 0;
}

 

728x90
반응형