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월 8일 #12

Open
wants to merge 5 commits 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
42 changes: 42 additions & 0 deletions 10_이분탐색/10815.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//10_이분탐색 필수1: 10815

#include <iostream>
#include <algorithm>

using namespace std;

int n, m;
int arr[500000];

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

cin >> n;

for (int i = 0; i < n; i++) {
cin >> arr[i];
}

// 숫자 카드 오름차순 정렬
sort(arr, arr + n);

Choose a reason for hiding this comment

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

이분 탐색을 위해서는 자료가 정렬되어 있어야 한다는 성질을 잘 이용해주셨네요!👍


cin >> m;

for (int i = 0; i < m; i++)
{
int num;
cin >> num;

// 이분 탐색: 해당 숫자가 있는 경우
if (binary_search(arr, arr + n, num))

Choose a reason for hiding this comment

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

함수 사용 좋습니다!

{
cout << "1 ";
} else {
cout << "0 ";
}
}

return 0;
}
87 changes: 87 additions & 0 deletions 10_이분탐색/14500.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//10_이분탐색 필수2: 14500

#include <iostream>
#include <vector>

using namespace std;

int n, m, ans;
vector<vector<int>> map;
vector<vector<bool>> visit;
vector<int> dy = {-1, 1, 0, 0};
vector<int> dx = {0, 0, -1, 1};
Comment on lines +9 to +12
Copy link

Choose a reason for hiding this comment

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

계속해서 쓰이는 벡터들을 전역으로 선언해 주셨네요!👍


void dfs(int y, int x, int cnt, int sum, vector<vector<bool>>& visit)
{
if (cnt >= 4)
{
ans = max(ans, sum);
return;
}

for (int k = 0; k < 4; k++)
{
int ny = y + dy[k];
int nx = x + dx[k];

if (ny < 0 || nx < 0 || ny >= n || nx >= m || visit[ny][nx]) {
continue;
}

visit[ny][nx] = true;
dfs(ny, nx, cnt + 1, sum + map[ny][nx], visit);
visit[ny][nx] = false;
}
}

void check(int y, int x)
{
if (y < n - 2 && x < m - 1){
ans = max(ans, map[y][x] + map[y + 1][x] + map[y + 2][x] + map[y + 1][x + 1]);
}

if (y < n - 2 && x > 0){
ans = max(ans, map[y][x] + map[y + 1][x] + map[y + 2][x] + map[y + 1][x - 1]);
}

if (y < n - 1 && x < m - 2){
ans = max(ans, map[y][x] + map[y][x + 1] + map[y][x + 2] + map[y + 1][x + 1]);
}

if (y > 0 && x < m - 2){
ans = max(ans, map[y][x] + map[y][x + 1] + map[y][x + 2] + map[y - 1][x + 1]);
}
}
Comment on lines +37 to +54
Copy link

Choose a reason for hiding this comment

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

ㅜ 모양의 테트로미노에 대해 섬세하게 경우를 나눠 구현해 주셨네요. 코드도 간결해 보기 좋았습니다.👍 다만 해설강의에서 말씀드렸드시 dfs함수 내에서 cnt==2인 경우마다 현재 위치에서 다시 dfs를 진행하여 처리할 수도 있다는 점을 알아두시면 좋을 것 같습니다.


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

cin >> n >> m;
map.assign(n, vector<int>(m));
visit.assign(n, vector<bool>(m, false));

for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++) {
cin >> map[i][j];
}
}

for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
visit[i][j] = true;
dfs(i, j, 1, map[i][j], visit);

visit[i][j] = false;
check(i, j);
Comment on lines +76 to +80
Copy link

Choose a reason for hiding this comment

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

visit벡터를 사용하지 않아도 map벡터에 해당하는 칸의 수를 0으로 잠시 바꾸어두는 방식으로도 문제를 해결할 수 있습니다. 샘플코드 참고하셔서 한 번 알아두시는 것도 좋을 것 같습니다.😊

}
}

cout << ans << "\n";

return 0;
}
53 changes: 53 additions & 0 deletions 10_이분탐색/16401.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//10_이분탐색 필수3: 16401

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int m, n, result;
vector<int> arr;
Comment on lines +9 to +10

Choose a reason for hiding this comment

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

P3
알튜비튜에서는 정말 필요한 상황이 아닐 때에는 값이 무분별하게 수정되는 것을 막기 위해 전역변수 사용을 지양하고 있습니다! m, n, arr은 인자로 넘기고, result는 bs의 값으로 리턴하는 식으로 수정할 수 있을 것 같아요!


void bs(int s, int e)

Choose a reason for hiding this comment

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

매개변수 탐색으로 문제를 잘 풀어주셨네요!

{
if (s > e)
return;
int mid = (s + e) / 2;
int cnt = 0;

for (int i = 0; i < n; i++)
cnt += arr[i] / mid;

if (cnt >= m)
{
if (result < mid){
result = mid;
}
bs(mid + 1, e);
}
else {
bs(s, mid - 1);
}
Comment on lines +22 to +31

Choose a reason for hiding this comment

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

포인터를 움직이는 조건을 잘 찾아주셨어요!

}

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

cin >> m >> n;
arr.resize(n);

for (int i = 0; i < n; i++){
cin >> arr[i];
}

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

bs(1, arr[n - 1]);

Choose a reason for hiding this comment

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

과자의 길이가 최소와 최대가 될 때를 각각 잘 찾아주셨네요!


cout << result << "\n";

return 0;
}
50 changes: 50 additions & 0 deletions 10_이분탐색/2343.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//10_이분탐색 도전1: 2343

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
int n, m;
cin >> n >> m;

vector<int> lengths(n);

for (int i = 0; i < n; i++) {
cin >> lengths[i];
}

int left = *max_element(lengths.begin(), lengths.end());
int right = 10000 * n; // 최대 블루레이 크기

while (left < right)
{
int mid = (left + right) / 2;
int count = 1; // 블루레이 개수
int sum = 0; // 현재 녹화된 길이

for (int i = 0; i < n; i++)
{
if (sum + lengths[i] > mid)
{
count++;
sum = 0;
}
sum += lengths[i];
}

if (count <= m) {
right = mid;
}
else {
left = mid + 1;
}
}

cout << left << "\n";

return 0;
}
58 changes: 58 additions & 0 deletions 10_이분탐색/3079.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//10_이분탐색 도전2: 3079

#include <iostream>
#include <vector>

using namespace std;

long long MIN_TIME = 1;
long long MAX_TIME = 1000000000LL * 1000000000LL;

bool checkInTime(vector<int>& input, int n, int m, long long time)
{
long long peopleCnt = 0;
for (int i = 0; i < n; i++)
{
peopleCnt += (time / input[i]);
if (peopleCnt >= m) {
return true;
}
}
return false;
}

long long binarySearch(vector<int>& input, int n, int m)
{
long long result = MAX_TIME;
long long start = MIN_TIME;
long long end = MAX_TIME;

while (start <= end) {
long long mid = (start + end) / 2;
if (checkInTime(input, n, m, mid))
{
end = mid - 1;
result = mid;
}
else {
start = mid + 1;
}
}
return result;
}

int main()
{
int n, m;
cin >> n >> m;
vector<int> input(n);

for (int i = 0; i < n; i++) {
cin >> input[i];
}

long long answer = binarySearch(input, n, m);
cout << answer << ""\n;

return 0;
}