Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[이분탐색] 10월 7일 #9

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions 10월 7일 - 이분탐색/17503.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
typedef pair<long long, long long> p;

bool cmp(const p& a, const p& b) {
return a.second > b.second;
}

//레벨이 beer[mid].first일 때 최대 선호도 값을 구하는 함수
long long int calPre(int mid, int n, vector<p> beer) {
long long int level = beer[mid].first;
long long int sum = 0, cnt = 0;

//선호도 순으로 정렬(실제 beer 벡터는 바뀌지 않음)
sort(beer.begin(), beer.end(), cmp);
for (int i = 0; i < beer.size(); i++) {
if (beer[i].first > level) {
//현재 level에서 못 먹는 술이면 패스
continue;
}
sum += beer[i].second;
if (++cnt == n) {
//상위 n개만 합산 후 리턴
return sum;
}
}

//n개를 채우지 못할 경우 -1 리턴(항상 m보다 작은 값)
return -1;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥰🥰


int binarySearch(int left, int right, int n, int m, vector<p> &beer) {
while (left <= right) {
int mid = (left + right) / 2;
long long int pre = calPre(mid, n, beer);

if (pre < m) {
//레벨이 mid일 때 선호도가 m보다 작다면 레벨을 올려줌
left = mid + 1;
}

else {
//그렇지 않다면 레벨이 낮아도 되므로
//레벨 값을 낮춰줌
right = mid - 1;
}
}

return beer[left].first;
}

int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);

int n, m, k;

cin >> n >> m >> k;
vector<p> beer(k);

for (int i = 0; i < k; i++) {
cin >> beer[i].second;
cin >> beer[i].first;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. 혹시 따로 입력받으신 이유가 있으실까요?

}
sort(beer.begin(), beer.end(), cmp);
long long int sum = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p2. sum의 범위는 200,000 * 10,000 로 int 범위 이내이므로 int 형을 사용해주었어도 되었을 것 같아요!


for (int i = 0; i < n; i++) {
sum += beer[i].second;
}

if (sum < m) {
//레벨이 최대여도 만족 안 되는 경우 먼저 계산
cout << "-1";
return 0;
}

sort(beer.begin(), beer.end());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p2. 탐색 범위를 더 줄일 수 있을 것 같아요! 입력받는 맥주들의 도수 레벨 중 최댓값보다 도수 레벨을 높일 경우는 없을 테니까, 입력받는 도수레벨 중 최댓값을 right포인터로 설정하면 어떨까요?

cout << binarySearch(0, k - 1, n, m, beer);

return 0;
}
50 changes: 50 additions & 0 deletions 10월 7일 - 이분탐색/3079.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//시간이 mid일 때 심사할 수 있는 최대 사람 수를 계산하는 함수
unsigned long long calPeople(unsigned long long mid, vector<unsigned long long>& entry) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3
long long 많이 쓰니까 typedef long long ll; 로 선언하고 사용하면 어떨까요?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사람 수 구하는 부분 따로 함수화 해주신거 너무 좋아요~👍

unsigned long long sum = 0;
for (int i = 0; i < entry.size(); i++) {
sum += mid / entry[i];
}

return sum;
}

unsigned long long binarySearch(unsigned long long left, unsigned long long right, int m, vector<unsigned long long>& entry) {
while (left <= right) {
unsigned long long mid = (left + right) / 2;
unsigned long long people = calPeople(mid, entry);

//mid초동안 m명의 사람을 심사할 수 없다면 mid를 늘려주고,
//mid초동안 심사할 수 있는 사람이 m보다 크거나 같다면 초를 줄여줌
if (people >= m) {
right = mid - 1;
}
else {
left = mid + 1;
}
}

return left;
}

int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);

unsigned long long n, m;
cin >> n >> m;
vector<unsigned long long> entry(n);
for (int i = 0; i < n; i++) {
cin >> entry[i];
}
sort(entry.begin(), entry.end());

cout << binarySearch(entry[0], entry[0] * m, m, entry);

return 0;
}