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

1-InSange #3

Merged
merged 1 commit into from
Mar 14, 2024
Merged
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
118 changes: 118 additions & 0 deletions InSange/BFS/13913.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include <iostream>
#include <queue>
#include <stack>
#include <cstring>

using namespace std;

const int MAX_INT = 9999999;

int N, K;
pair<int, int> visited[100001];
queue<int> q; // ���� �̵��ؾ��� ĭ���� BFS�� �湮�ϱ� ���ؼ� ť�� ����
stack<int> st; // ������(K)���� ��Ʈ��ŷ�� ���� �����(N)���� �湮�ߴ� ������ �־� ������� ����ϱ� ���� ������ ����

Choose a reason for hiding this comment

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

사실 stack의 역할은 vector로 완벽하게 대체 가능합니다. push()는 push_back(), pop()은 pop_back()에 대응되죠.
vector를 쓰게 되면 배열 중간에 위치한 요소도 접근이 가능해서 좋습니다. stack은 그게 불가능하거든요 :)


bool Check(int index)
{ // �̵��� �� �ִ� �� ����( 0 <= x <= 100,000 )�� ����� �ȵȴ�!
if (index < 0 || index > 100000) return false;
return true;
}
Comment on lines +15 to +19

Choose a reason for hiding this comment

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

함수명을 좀 더 직관적으로 알 수 있게 적으면 좋을 것 같네요.
개인적으로 저는 아래와 같이 작성합니다.

bool OutOfBound(int index)
{
    return index < 0 || index > 100000;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

참고하겠습니다!
확실히 어디에 필요한지 좀 더 명시적이면 좋겠네용


void Init()
{ // ������(N : �����)�� ����(K : ������) �� ����
cin >> N >> K;
// 0 ��° �ε����� ������ ���ϱ� ������ MAX_INT�� �ʱ�ȭ ���ش�.
// ù��° ���� �ش� ��ȣ�� �湮�ϱ� ������ ��ȣ�� �����ϰ�, �ι�° ���� �ش� ��ȣ�� ��������� Ƚ���� �����Ѵ�.
for (int i = 0; i < 100001; i++)
{
visited[i] = { MAX_INT, MAX_INT };
}
// ��� ������ 0�� Ƚ���� ä���ֱ�
visited[N] = { N, 0 };
Comment on lines +26 to +31
Copy link

@9kyo-hwang 9kyo-hwang Mar 12, 2024

Choose a reason for hiding this comment

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

pair<int, int> visited[100001]; 대신 vector<pair<int, int>> visited;로 쓰면 좀 더 편리할 것 같습니다. 이렇게 하면

visited.assign(100001, {MAX_INT, MAX_INT})

이런 식으로 간편하게 초기화할 수 있거든요 :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

동적으로 데이터를 추가할때를 제외하고는 vector를 잘 안쓰다보니 해당 방식의 초기화는 몰랐네요!
좋은 정보 하나 알아갑니다~

}

void Solve()
{ // 3������ ����� ��
if (N == K) // 1. ����(N)�� ����(K)�� ���� ��ġ�� ���� ��� �̵��ϴ� ĭ�� 0�̰� �ش� ��ġ�� �ٷ� ������ش�.
{
cout << visited[N].second << "\n" << N;
return;
}
else if (N > K) // 2. ����(N)�� ����(K)���� ū ��� K�� �����ϴ� ������ -1 �ۿ� ���� ������ -1�θ� ����� ������ ������ش�.
{
cout << N-K << "\n";
while (N != K)
{
cout << N << " ";
N--;
}
cout << N << "\n";
return;
}
else// if(N < K) // 3. ����(N)�� ����(K)���� ���� ��� +1, *2 �Ӹ� �ƴ϶� -1 * 2�� ���� ������ ��� ������ �ִ�. ex) 5���� 8�� �� ��� (1) 5 -> 4 -> 8 (2) 5 -> 10 -> 9 -> 4
Comment on lines +41 to +52

Choose a reason for hiding this comment

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

사실 return을 걸어줬으면 else if로 분기할 필요는 없죠.

if (N == K)
{
    ...
    return;
}

if(N > K)
{
    ...
    return;
}

...
return;

이런 식으로 하면 아래 else 분기의 indent를 줄일 수 있을 것 같네요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

사람들에게 3가지 방법에 대해서 좀 더 직관적으로 보여줄 수 있는 방법이 뭐가 있을까 고려하다보니 깜빡했습니다!
지적 감사합니다~

{
// ������(N: �����) ���� �־��ش�.
q.push(N);

while (!q.empty())
{ // ���� �������� ��ġ�� ť���� �����ش�.
int cur_num = q.front();
q.pop();
// ���� �̵��� ĭ�� ���� ���� �̵��� ���� ���� ��ġ ���� ������ �������� �������ش�.
int cur_cnt, next_num;
cur_cnt = visited[cur_num].second;
// ���� ��ġ���� -1��ŭ �̵����� ���.
next_num = cur_num - 1;
if (Check(next_num) && visited[next_num].second > cur_cnt + 1)
{
q.push(next_num);
visited[next_num].first = cur_num;
visited[next_num].second = cur_cnt + 1;
}
if (next_num == K) break;
// ���� ��ġ���� +1��ŭ �̵����� ���.
next_num = cur_num + 1;
if (Check(next_num) && visited[next_num].second > cur_cnt + 1)
{
q.push(next_num);
visited[next_num].first = cur_num;
visited[next_num].second = cur_cnt + 1;
}
if (next_num == K) break;
// ���� ��ġ���� *2��ŭ �̵����� ���.
next_num = 2 * cur_num;
if (Check(next_num) && visited[next_num].second > cur_cnt + 1)
{
q.push(next_num);
visited[next_num].first = cur_num;
visited[next_num].second = cur_cnt + 1;
}
Comment on lines +65 to +89

Choose a reason for hiding this comment

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

요거 반복문을 이용하면 코드 중복을 줄일 수 있습니다.

for(int offset_num : {-1, +1, cur_num})
{
    int next_num = cur_num + offset_num;
    if(!Check(next_num) || visited[next_num] <= cur_cnt + 1)
    {
        continue;
    }
    q.push(next_num);
    visited[next_num] = {cur_num, cur_cnt + 1};
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

이거는 확실히 도움이되네요!
for문을 많이 사용하지만 가장 기본적으로만 활용하다보니 이렇게 다양하게 접근하는 방법은 익숙치 않은 것 같습니다.
확실히 좀 더 명확하고 짧게 확인할 수 있다는 점에서 좋네요.
습관을 들여보도록 노력하겠습니다.

if (next_num == K) break;
}
// ��������� ���������� ���µ� �ɸ� ĭ�� ��
cout << visited[K].second << "\n";
// ���������� ��������� �湮�ߴ� ������ �����Ͽ� ��� �����Ҷ��� K->N������ ����Ҷ��� N->K�� ����� ��!
do {
st.push(K);
K = visited[K].first;
} while (K != N);
st.push(N);

while (!st.empty())
{
cout << st.top() << " ";
st.pop();
}
}
}

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

Init();
Solve();

return 0;
}
3 changes: 2 additions & 1 deletion InSange/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

| 차시 | 날짜 | 문제유형 | 링크 | 풀이 |
|:----:|:---------:|:----:|:-----:|:----:|
| 1차시 | 2023.10.27 | BFS | - | - |
| 1차시 | 2024.03.11 | BFS | [숨바꼭질 4](https://www.acmicpc.net/problem/13913) | - |
=======
---