-
Notifications
You must be signed in to change notification settings - Fork 0
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
Conversation
별도 solve 함수랑 return 문을 사용하는 경우 else if, else는 없어도 될 것 같아요! |
햄 리뷰 달 때 "add a single comment" 말고 "approve"로 해야 리뷰어즈 리퀘스트가 체크돼요 |
int N, K; | ||
pair<int, int> visited[100001]; | ||
queue<int> q; // ���� �̵��ؾ��� ĭ���� BFS�� �湮�ϱ� ���ؼ� ť�� ���� | ||
stack<int> st; // ������(K)���� ��Ʈ��ŷ�� ���� �����(N)���� �湮�ߴ� ������ �־� ������� ����ϱ� ���� ������ ���� |
There was a problem hiding this comment.
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; | ||
} |
There was a problem hiding this comment.
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;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
참고하겠습니다!
확실히 어디에 필요한지 좀 더 명시적이면 좋겠네용
for (int i = 0; i < 100001; i++) | ||
{ | ||
visited[i] = { MAX_INT, MAX_INT }; | ||
} | ||
// ��� ������ 0�� Ƚ���� ä���ֱ� | ||
visited[N] = { N, 0 }; |
There was a problem hiding this comment.
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})
이런 식으로 간편하게 초기화할 수 있거든요 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
동적으로 데이터를 추가할때를 제외하고는 vector를 잘 안쓰다보니 해당 방식의 초기화는 몰랐네요!
좋은 정보 하나 알아갑니다~
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 |
There was a problem hiding this comment.
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를 줄일 수 있을 것 같네요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사람들에게 3가지 방법에 대해서 좀 더 직관적으로 보여줄 수 있는 방법이 뭐가 있을까 고려하다보니 깜빡했습니다!
지적 감사합니다~
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; | ||
} |
There was a problem hiding this comment.
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};
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거는 확실히 도움이되네요!
for문을 많이 사용하지만 가장 기본적으로만 활용하다보니 이렇게 다양하게 접근하는 방법은 익숙치 않은 것 같습니다.
확실히 좀 더 명확하고 짧게 확인할 수 있다는 점에서 좋네요.
습관을 들여보도록 노력하겠습니다.
저는 요렇게 풀어봤습니다 :) #include <iostream>
#include <vector>
#include <queue>
#include <numeric>
using namespace std;
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int N, K; cin >> N >> K;
vector<int> Distances(100001, -1);
vector<int> Parents(100001, 0);
iota(Parents.begin(), Parents.end(), 0);
deque<int> Q;
Q.emplace_back(N);
Distances[N] = 0;
while(!Q.empty())
{
const int X = Q.front();
Q.pop_front();
if(X == K)
{
cout << Distances[X] << "\n";
break;
}
for(const int D : {X, -1, 1})
{
int NX = X + D;
if(NX < 0 || NX > 100000 || Distances[NX] != -1 && Distances[NX] < Distances[X] + 1)
{
continue;
}
Distances[NX] = Distances[X] + 1;
Parents[NX] = X;
Q.emplace_back(NX);
}
}
deque<int> Paths;
int Pos = K;
while(Pos != N)
{
Paths.emplace_front(Pos);
Pos = Parents[Pos];
}
Paths.emplace_front(Pos);
for(const int Path : Paths)
{
cout << Path << " ";
}
return 0;
} |
우선순위큐...? 우선순위큐를 어떤 식으로 적용할 수 있을까요? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
범위 체크함수 와 초기화 함수 , solve 함수 를 분리하면서 코드가 깔끔해지는 것 같습니다
그리고 visited 배열을 pair<int,int>형으로 두는 방식이 색달랐던거 같습니다. 잘 배워갑니다..!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 줄일 수 있는 부분은 줄이는 연습을 해야겠네요
문제 재밌어보이네요 저도 풀러 갑니다 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
visited 배열로 경로를 찾는 게 신기했어요. 저도 중복을 피하는 방법에 대해 고민을 많이 했었는데 많이 배워갑니다. 그리고 1번째 풀이부터 마지막 풀이까지 잘 정리되어 있어서 읽기 정말 편했습니다.
그럼요~ |
🔗 문제 링크
숨바꼭질 4
✔️ 소요된 시간
3시간
✨ 수도 코드
BFS문제입니다.
수빈이가 동생의 위치까지 도착하는데 걸리는 이동 수와 거기까지의 경로를 출력해야 합니다.
이동할 수 있는 크기는 현재 수빈이의 위치 N에서 -1, +1 또는 *2 만큼 이동이 가능합니다.
첫번째 풀이
출발지에서 도착지까지 탐색하는 과정은 BFS를 사용하여 현재 위치 N에서 +1, -1, *2 를 곱해 다음 위치 값이 0 <= x <= 100000 사이에 들어있다면 큐에 계속 집어 넣는 식으로 하였습니다.
하지만 이럴 경우 이전에 방문했던 위치에 다시 재방문하는 경우가 발생해 중복이 발생하게 됩니다.
중복 방문을 피하기 위해서 visited 배열을 선언을 해주었고 해당 배열 안에 현재 위치까지 오는데 걸린 이동 횟수를 집어 넣어주었습니다.
pair<int, int>로 선언을 한 이유는 { 이전에 방문했던 노드 인덱스 값, 현재 노드까지 이동하는데 걸린 수 }로 저장하기 위하여 선언을 해 주었습니다.
두번째 풀이
두번째 풀이에서는 만약 수빈이와 동생의 위치가 같을 때의 예외 사항을 추가해줬습니다.
마지막 풀이
https://forward-gradually.tistory.com/72
위의 링크에서 반례들을 참고하게 되었고
수빈이의 위치가 동생의 위치보다 큰 경우와 수빈이의 위치가 동생의 위치보다 작은 경우로 나눠주는 예외를 처리해주었습니다.
📚 새롭게 알게된 내용
반례 참고 : https://forward-gradually.tistory.com/72