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

[이분탐색] 11월 5일 #12

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
31 changes: 31 additions & 0 deletions BOJ_10815.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int binarySearch(const vector<int>& arr, int target) {
int left = 0, right = arr.size() - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target) return 1;
else if (arr[mid] > target) right = mid - 1;
else left = mid + 1;
}
Comment on lines +8 to +13

Choose a reason for hiding this comment

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

이분탐색의 원리를 잘 이해하고 구현해주셨네요 멋있습니다 :3

return 0;
}

int main() {
int n, m;
cin >> n;
vector<int> arr(n);
for (int& x : arr) cin >> x;
sort(arr.begin(), arr.end());

cin >> m;
vector<int> targets(m);
for (int& x : targets) cin >> x;

for (int target : targets) {
cout << binarySearch(arr, target) << " ";
}
}
58 changes: 58 additions & 0 deletions BOJ_16401.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//과자를 나눠줄 수 있는 최대 길이를 이진 탐색을 통해 찾는 함수
int getMaxSnackLength(int numPeople, const vector<int>& snackLengths) {
int left = 1, right = *max_element(snackLengths.begin(), snackLengths.end());

Choose a reason for hiding this comment

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

매개변수 탐색을 위한 초깃값을 잘 설정해주셨네요 💯

int maxSnackLength = 0;

while (left <= right) {
int mid = (left + right) / 2; //중앙값(과자 길이)
int count = 0;

//각 과자 길이를 현재 중앙값(mid)로 나눠 몇 명에게 나눠줄 수 있는지 계산
for (int length : snackLengths) {
count += length / mid;
}
Comment on lines +14 to +19

Choose a reason for hiding this comment

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

P3. 길이가 mid일 때 나누어줄 수 있는 조각의 수를 구하는 부분도 함수로 빼면 좋겠네요 🤗🤗


//나눠줄 수 있는 사람이 원하는 수(numPeople) 이상인 경우
if (count >= numPeople) {
maxSnackLength = mid; //가능한 과자 길이 중 최대값 저장
left = mid + 1; //더 큰 길이로 탐색
} else {
right = mid - 1; //더 작은 길이로 탐색
}
}
return maxSnackLength;
}

// 사용자 입력을 받아 과자 길이 배열을 반환하는 함수
vector<int> getInputArray(int size) {
vector<int> array(size);
for (int& length : array) {
cin >> length;
}
return array;
}
Comment on lines +32 to +39

Choose a reason for hiding this comment

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

P2. 함수화 좋습니다! 그런데 알튜비튜에서는 입출력은 메인에서 받고, 주요 로직은 각 함수에서 구현하는 방식으로 제안드리고 있으니 참고해주세요 😊


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

//인원 수와 과자 개수 입력
int numPeople, numSnacks;
cin >> numPeople >> numSnacks;

//과자 길이 배열 입력
vector<int> snackLengths = getInputArray(numSnacks);
Comment on lines +47 to +51

Choose a reason for hiding this comment

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

P3. 변수명은 스네이크 코드 형식을 따라주세요!

int hello_world;      // 변수
int helloWorld()      // 함수
const int HELLO_WORLD // 상수


//나눠줄 수 있는 최대 과자 길이를 계산하고 출력
int result = getMaxSnackLength(numPeople, snackLengths);
cout << result << "\n";

return 0;
}
Comment on lines +41 to +58

Choose a reason for hiding this comment

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

메인함수 깔끔하고 좋습니다👍👍👍

55 changes: 55 additions & 0 deletions BOJ_17266.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <iostream>
#include <algorithm>
#include <climits>

using namespace std;
const int INF = INT_MAX;

int calculateMinRadius(int roadLength, int shelterCount, int shelters[]) {
int minRadius = INF; //최소 반지름을 무한대 값으로 초기화
int left = 0, right = 100000; //이진 탐색 범위 설정 (반지름)

while (left <= right) {
int radius = (left + right) / 2; // 중간값(반지름) 계산
bool canCover = true; //모든 구간을 커버할 수 있는지 확인하는 플래그

//첫 번째 시작 지점을 커버할 수 있는지 확인
if (shelters[0] > radius) canCover = false;

//반지름 내에서 커버 가능한지 확인
for (int i = 0; i < shelterCount - 1; i++) {
if (shelters[i + 1] - shelters[i] > radius * 2) {
canCover = false;
break;
}
}

//도로의 끝 지점을 커버할 수 있는지 확인
if (roadLength - shelters[shelterCount - 1] > radius) canCover = false;

// 모든 지점이 커버되지 않으면, 반지름을 늘려 탐색 범위를 오른쪽으로 조정
if (!canCover) {
left = radius + 1;
} else {
//모든 지점이 커버될 경우, 최소 반지름 갱신 후 탐색 범위를 왼쪽으로 조정
minRadius = min(minRadius, radius);
right = radius - 1;
}
}
return minRadius;
}

int main() {
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
int roadLength, shelterCount;
cin >> roadLength >> shelterCount;
int shelters[shelterCount];
for (int i = 0; i < shelterCount; i++) cin >> shelters[i];

//최소 반지름을 계산하고 결과 출력
int minRadius = calculateMinRadius(roadLength, shelterCount, shelters);
cout << minRadius;

return 0;
}
38 changes: 38 additions & 0 deletions BOJ_2343.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int count(const vector<int>& lengths, int maxLen) {
int disks = 1, sum = 0;
for (int len : lengths) {
if (len > maxLen) return lengths.size() + 1;
if (sum + len > maxLen) { disks++; sum = len; }
else sum += len;
}
return disks;
}

int min(int max, const vector<int>& lengths) {
int left = *max_element(lengths.begin(), lengths.end()), right = 0;
for (int len : lengths) right += len;
int result = right;

while (left <= right) {
int mid = (left + right) / 2;
if (count(lengths, mid) <= max) {
result = mid;
right = mid - 1;
} else left = mid + 1;
}
return result;
}

int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int n, m; cin >> n >> m;
vector<int> lengths(n);
for (int& len : lengths) cin >> len;
cout << min(m, lengths);
}
56 changes: 56 additions & 0 deletions BOJ_3079.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//필요한 시간 계산하는 함수
long long calculateResources(long long time, const vector<long long>& times) {
long long totalResources = 0;
for (long long t : times) {
totalResources += (time / t); //주어진 시간으로 각 자원에서 얻을 수 있는 총 개수
}
return totalResources;
}

//최소 시간을 찾는 이진 탐색 함수
long long findMinimumTime(int numResources, long long requiredResources, const vector<long long>& times) {
long long left = 1; //최소 시간
long long right = times[0] * requiredResources; //최대 시간
long long minTime = 0;

while (left <= right) {
long long mid = (left + right) / 2; //중간값

long long totalResources = calculateResources(mid, times);

if (totalResources < requiredResources) {
left = mid + 1; //필요 시간이 부족한 경우 더 큰 시간 탐색
} else {
minTime = mid; //필요 시간이 충족되는 경우 최소 시간 갱신
right = mid - 1; //더 작은 시간 탐색
}
}

return minTime;
}

int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

int n, m;
cin >> n >> m;

vector<long long> times(n); //각 자원의 시간 저장

for (int i = 0; i < n; i++) {
cin >> times[i]; //자원 별로 필요한 시간 입력
}

sort(times.begin(), times.end()); //시간 정렬

//최소 시간 계산 및 출력
long long result = findMinimumTime(n, m, times);
cout << result << endl;

return 0;
}