3-G 테스트케이스 질문드립니다.
안녕하세요 선생님! 선생님의 해설 잘 들었습니다.
다만 제 코드가 어떤 테스트케이스에서 걸리는지 도저히 모르겠어요. 3시간 넘게 테스트케이스만 만들고 테스트해봤는데 다 잘 되고 있어서..
제 코드는 다음과 같이 구현되어 있어요.
경우의 수는 더하기라는 것을 활용
노드의 level(depth,거리) 단위로 bfs 진행
이를 위해 정적으로 size 활용한 while(size--) 활용visited, cnt 배열로 각각 최소 거리와 최소 시간을 도출해냄
다만 제 코드의 유의할점은 prevLoopNum과 loopNum을 사용한다는 점이에요. 이는
0 -> 1 ---(더하기 1)--> 2 0 -> 1 ---(곱하기 2)---> 2와 같은 경우에 서로 다른 경로로 인식되는 경우를 방지하기 위함이에요. 즉,
입력: 0 3
출력:
3
1이 나오도록 만들기 위함이에요.
https://www.acmicpc.net/source/share/cc7572065f6146b8850e8ee371089353
Câu trả lời 2
1
안녕하세요 케이님 ㅎㅎ
상당히 잘 짜셨네요 ㅎㅎ 코드가 우아합니다.
와 같은 경우에 서로 다른 경로로 인식되는 경우를 방지하기 위함이에요. 즉,
-> 아닙니다. 그 경우에도 다른 경로로 인식되어야 합니다. 0 3은 2가 되어야 합니다.
1.
cur > MAXPOS
-> 이부분 때문에 틀립니다. 이렇게 되면 cur은 MAXPOS를 참조할 수 있는데 배열 끝을 참조하게 됩니다. 배열을 + 1 또는 + 4로 더 크게 설정해야 합니다.
2
loopnum
int prevLoopNum = size - 1;
while(size--){//이 loop 자체가 위계 (해당 loop 내에서는 동일한 위계, 즉 동일한 거리를 가짐)
int loopNum = size;이게 이해가 안가는코드인데요. 저부분은 아마 위쪽과 아래쪽 루프를 구분하고자 함인 것 같은데 -> queue의 사이즈가 같은 순간에는 구분이 안되지 않나요? 그리고 애초에 왜 필요한지 모르겠습니당..
수정된 코드는 다음과 같습니다. 나머지부분은 잘 하셨습니다.
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
const int MAX_POS = 100000;
int n,k;
int visited[MAX_POS + 1]; //거리(시간)으로도 사용
int cnt[MAX_POS + 1]; //해당 node에 최소시간으로 도달한 경우의 수
void bfs(int start){
queue<int> q;
q.push(start);
visited[start] = 1; cnt[start] = 1;
while(q.size()){
int size = q.size(); //정적으로 계산
bool endFlag = false; //최단 거리 찾으면 불필요하게 찾지 않고 탈출
int prevLoopNum = size - 1;
while(size--){//이 loop 자체가 위계 (해당 loop 내에서는 동일한 위계, 즉 동일한 거리를 가짐)
int loopNum = size;
int prev = q.front(); q.pop();
//+1, -1, *2 진행
for(int i = 0; i < 3; i++){
int cur;
switch(i){
case 0:
cur = prev + 1;
break;
case 1:
cur = prev - 1;
break;
case 2:
cur = prev * 2;
break;
default:
throw runtime_error("도달해서는 안됩니다.");
}
if(cur < 0 || cur > MAX_POS) continue;
if(!visited[cur]){
q.push(cur);
cnt[cur] += cnt[prev]; //경우의 수는 더하기!!! (단순하게 cnt[cur]++ 하지말것)
visited[cur] = visited[prev] + 1;
}else if(visited[cur] == visited[prev] +1){
//루프 번호가 다르다 == 다른 곳에서 온 경우.
//그러나 안티패턴이라 생각. 뜻을 주석 없이는 파악하기 어렵고 버그 유발이 쉬움
cnt[cur]+= cnt[prev];
}
}
prevLoopNum = loopNum;
}
if(endFlag) return;
}
}
int main(){
cin >> n >> k;
bfs(n);
cout << visited[k] - 1 << "\n" << cnt[k] << "\n";
return 0;
}
또 질문 있으시면 언제든지 질문 부탁드립니다.
좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)
감사합니다.
강사 큰돌 올림.
0
좋은 답변 감사합니다! ㅎㅎ
0~100,000 까지 가능하면 인덱스는 당연히 100,001이어야 하는데 착각했네요..ㅎㅎ
loopNum 과 관련된 코드는 문제 자체를 잘못 이해해서 생긴 코드였어요. (0 3을 1로 해야한다는 오해)
덕분에 문제를 제대로 이해했고, 해당 부분의 코드는 제거해서 제출했어요! 감사합니다 :)
교안 158페이지 문의드립니다
0
10
2
코딩살구클럽 관련 건의사항
0
29
1
코살에 19942 다이어트 문제에 N의 범위가 빠져있슴니다
0
13
1
진행 방법 질문드립니다!
0
46
2
2-I) 왜 이 문제가 그래프이론 카테고리에 있는지 잘 모르겠습니다.
0
56
2
2주차 개념#12 트리 순회
0
26
2
백준사이트가 종료된다고 합니다.
0
286
2
백준 서비스 종료
9
890
1
sk 하이닉스 코테 대비
0
368
2
3-G 최댓값 질문
0
51
1
모듈러 연산 값이 10이 아닌 경우도 있지 않나요?
0
83
2
3-I 코드 질문드립니다.
0
62
2
3-N 질문 있습니다.
0
66
2
학습방법
0
102
2
4-H 질문 있습니다 (코드 리뷰)
0
66
2
코딩테스트 어디까지 준비해야 하는지 질문이 있습니다.
0
170
2
2-O 반례가 무엇일지 어떤 부분이 틀렸는지 잘 모르겠습니다.
0
69
2
2주차 개념 #4-2. 인접행렬 질문있습니다.
0
64
2
1-A 문제풀이 후 궁금한 점이 생겨서 질문드립니다.
0
51
2
조합 재귀 풀이 확인 해주시면 감사하겠습니다.
0
68
2
함수별 시간복잡도
0
73
2
3-h 질문입니다.
0
49
1
안녕하세요 선생님. 시간 복잡도 4번 질문있습니다.
0
53
2
1-I 문제 질문 드립니다.
0
76
2

