BOJ

BOJ 28068 - I Am Knowledge

playdeom 2024. 5. 8. 22:04

 

문제가 원하는 것은 마법사가 책을 자지 않고 다 읽을 수 있는지 판별해 주는 것이다.

마법사는 책을 읽을 때 즐거움 ai 만큼 소모하고 다 읽으면 bi 만큼 즐거움을 얻는다.

 

관찰 1.

우선 ai ≤ bi인 책을 읽으면 읽기 전보다 즐거움이 감소하지 않는다.

따라서 이런 책만 읽을 때에는 ak가 작은 순서대로 읽으면 된다.

 

관찰 2.

다음으로 ai > bi인 경우이다.

이 경우 책을 읽을 때마다 즐거움이 감소한다.

따라서 책을 거꾸로 읽는 방법을 생각해 보면 되는데 이 경우에는 관찰 1번과 같은 방법을 사용하면 된다.

그렇기에 bi가 큰 순서대로 읽으면 된다.

 

이제 즐거움이 감소하지 않는, 이득이 되는 책을 전부 읽은 후 이득이 되지 않는 책을 읽으며

즐거움이 0 밑으로 떨어지는지 확인하면 정답을 구할 수 있다.

 

처음에는 단순히 우선순위 큐에 넣고 ai 값이 작은 순으로 빼서 확인하는 식으로 하면 되는 줄 알았지만 아니었다..

생각보다 어려웠던 문제였다.


소스코드

더보기
#include <bits/stdc++.h>
#define endl "\n"
#define upgrade ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
bool cmp(pair<ll, ll>a, pair<ll, ll>b) {
	if (a.first == b.first)return a.second < b.second;
	return a.first < b.first;
}
bool cmp2(pair<ll, ll>a, pair<ll, ll>b) {
	return a.second > b.second;
}
int main() {
	upgrade;
	int n;
	cin >> n;
	vector<pair<ll, ll>>p;
	vector<pair<ll, ll>>m;
	for (int i = 0; i < n; i++) {
		int a, b;
		cin >> a >> b;
		if (a <= b)p.push_back({ a,b });
		else m.push_back({ a,b });
	}
	sort(all(p), cmp);
	sort(all(m), cmp2);
	ll happy = 0;
	for (int i = 0; i < p.size(); i++) {
        happy -= p[i].first;
		if (happy < 0) {
			cout << 0;
			return 0;
		}
		happy += p[i].second;
	}
	for (int i = 0; i < m.size(); i++) {
        happy -= m[i].first;
		if (happy < 0) {
			cout << 0;
			return 0;
		}
		happy += m[i].second;
	}
	cout << 1;
	return 0;
}
 

 

 

'BOJ' 카테고리의 다른 글

BOJ 16225 - 제271회 웰노운컵  (0) 2024.05.10
BOJ 13873 - Hotel Rewards  (0) 2024.05.09
BOJ 30108 - 교육적인 트리 문제  (0) 2024.04.26
BOJ 13306 - 트리  (0) 2024.04.18
BOJ 20194 - 경계 로봇  (2) 2024.01.31