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

[투 포인터] 2171024 신수정 #312

Open
wants to merge 144 commits into
base: 2171024-신수정
Choose a base branch
from

Conversation

chock-cho
Copy link

인적사항

학번: 2171024
이름: 신수정


과제 제출

기존 제출 : 20437, 20922, 2473
추가 제출 : 13422, 14503


13422, 14503은 계속 틀렸다고 나오는데, 어느 부분에서 제가 자꾸 놓치고 있는 건지 알려주시면 감사하겠습니다... 😥😥

jk0527 and others added 30 commits February 21, 2023 20:56
jk0527 and others added 25 commits April 14, 2023 09:45
@chock-cho chock-cho changed the base branch from main to 2171024-신수정 May 16, 2023 06:01
@chock-cho chock-cho changed the title [2171024 신수정] 투 포인터 [투 포인터] 2171024 신수정 May 16, 2023
Copy link
Contributor

@kimyu0218 kimyu0218 left a comment

Choose a reason for hiding this comment

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

[투 포인터 구현 코드 리뷰 완료]

14503 (P1)

수정님 안녕하세요!
구현 문제 확인했습니다! 🥰
오류 원인들은 해당 코드 위치에 적어드렸어요~
오류 원인 외에도 몇 가지 코멘트 드렸습니다.
궁금한 점이 있으면 리뷰어를 호출해주세요!

Comment on lines +33 to +46
int goBackDir(int &dir){ // 현재 방향에서 후진 구현
if(dir == NORTH){
return WEST;
}
else if(dir == EAST) {
return SOUTH;
}
else if(dir == SOUTH) {
return NORTH;
}
else {
return EAST;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

오류 발생 요인 첫번째입니다!! 후진 방향이 잘못되었습니다. NORTH의 반대 방향은 WEST가 아니라 SOUTH죠. EAST도 마찬가지로 SOUTH가 아니라 WEST 입니다. 하지만 이렇게 하드코딩 하지 않고 인덱스로 후진을 구현할 수 있어요.
예를 들어봅시다. 북쪽의 반대 방향은 남쪽이죠. 북쪽은 0, 남쪽은 2이에요. 현재 방향에 2를 더한 값이 반대방향이 되겠네요 😊😊 하지만 남쪽의 반대 방향을 구할 경우 2+2=4가 되어 인덱스를 벗어나네요. 인덱스가 범위를 벗어나지 않도록 나머지 연산자를 활용하면 goBackDir이 필요하지 않아요🥰

Comment on lines +18 to +31
int convertDir(int &dir){ // 방향 전환
if(dir == NORTH) {
return WEST;
}
else if(dir == EAST) {
return NORTH;
}
else if(dir == SOUTH) {
return EAST;
}
else {
return SOUTH;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

convertDir도 마찬가지에요. 현재 북-동-남-서 순서로 방향 벡터에 표현되고 있죠. 북-동-남-서는 시계방향이므로 반시계 방향을 구현하기 위해서는 -1을 해주는 작업이 필요하겠죠? 😊

Comment on lines +55 to +57
if(nx < 0 || ny < 0 || nx >= N || ny >= M) {
continue;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

맞아요!! 일반적인 그래프 탐색의 경우 범위를 벗어나지 않는지 확인하는 과정이 반드시 필요해요. 하지만 이번 문제는 특별한 조건이 있어요 😊

방의 가장 북쪽, 가장 남쪽, 가장 서쪽, 가장 동쪽 줄 중 하나 이상에 위치한 모든 칸에는 벽이 있다.

즉, 방의 가장자리는 항상 벽이라는 의미입니다. x, y 는 청소해야 하는 빈 칸의 위치를 가리키죠? 따라서 방의 가장자리인 벽을 가리키는 경우는 없습니다. 벽을 가리키지 않으므로 범위를 벗어나는 일도 없겠죠? 😊😊

int prev_dir = goBackDir(dir);
int prev_x = x + dx[prev_dir];
int prev_y = y + dy[prev_dir];
if(prev_x >= 0 && prev_y >= 0 && prev_x < N && prev_y < M){ // 맵 탐색에 벗어나지 않고
Copy link
Contributor

Choose a reason for hiding this comment

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

위의 코멘트에 따르면 여기도 범위 체크가 없어도 되겠네요 🥰

void dfs(vector<vector<int>> &map, vector<vector<bool>> vis, int &N, int &M, int x, int y, int dir, int cnt) {
bool flag = false; // 현재 위치에서 4방향 탐색 했을 시 청소할 수 있는 좌표가 있다면
for(int i = 0; i < 4; i++){
int n_dir = convertDir(dir);
Copy link
Contributor

Choose a reason for hiding this comment

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

두번째 오류 원인입니다! dir은 (x,y)의 방향을 의미하죠. 후진을 구현하기 위해서 유지되어야 하는 값입니다.
for문 내부를 확인해볼까요? 4방향을 탐색한다고 되어있는데 실제로는 dir에서 반시계 방향으로 한 칸 움직인 것을 4번 검사하고 있네요🥲
북-동-남-서가 시계방향인 것을 바탕으로 반시계 회전을 구현해봅시다😊

vis[nx][ny] = true; // 해당 좌표 청소해주고
dfs(map, vis, N, M, nx, ny, n_dir, cnt+1);
}
if(!flag){ // 현재 위치에서 청소할 수 있는 좌표가 없다면 후진 oR 종료
Copy link
Contributor

Choose a reason for hiding this comment

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

세번째 오류 원인입니다! flag가 항상 false값을 가져요.

Comment on lines +74 to +77
else {
cout << cnt << "\n";
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

네번째 오류 원인입니다. 다른 모든 오류를 해결하시고 마지막으로 고민해보시면 될 것 같아요! 🥰
해당 코드를 실행시키면 cnt값이 여러번 출력될 거에요. return이 함수 종료를 의미하는 건 맞지만 현재 호출된 dfs를 종료시키거든요. dfs는 재귀함수이므로 자기 자신을 여러번 호출할 수 있는데 여러 개의 dfs중 현재 dfs만 종료된 것입니다.
어떻게 하면 dfs가 갈림길을 탐색하는 걸 막을 수 있을까요? return문을 어느 위치에 넣어야 할까요? 😊😊

cin >> map[i][j];
}
}
dfs(map, vis, N, M, st_x, st_y, st_d, 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

마지막 오류 원인입니다. 시작점에 대한 방문체크가 이루어지지 않았어요!!

Copy link

@kwakrhkr59 kwakrhkr59 left a comment

Choose a reason for hiding this comment

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

[투포인터 필수 알고리즘 코드 리뷰 완료]
안녕하세요 수정님~ 투포인터 필수 알고리즘 문제 코드리뷰 완료 되셨습니다😀 슬라이딩 윈도우와 투포인터 알고리즘을 잘 사용해서 문제를 풀이해주셨더라고요👍👍 상수 활용도 너무 좋았습니다! 코드 스타일 관련해서 몇 가지 코멘트 남겨드렸으니 확인해보시고 질문 있으시면 언제든 리뷰어로 호출해주세요:) 수고 많으셨습니다~

cnt[a[e]]++; //해당 값 증가시켜주고
e++; // 오른쪽 포인터 증가
}
len = max(len, abs(s-e));

Choose a reason for hiding this comment

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

투포인터 활용 너무 좋습니다😍😍


int main(){
ios_base::sync_with_stdio(false); cin.tie(0);
int N, K;

Choose a reason for hiding this comment

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

P3. 변수의 이름은 스네이크 표기법을, 상수의 이름은 대문자로 표기할 것을 권장해드리고 있습니다! 코드 컨벤션마다 달라질 수는 있지만, 변수와 상수의 구분을 확실하게 해주시면 더더욱 좋을 것 같네요😁

s++;
e++;
mx_len = max(mx_len, cur_len); // mx_len: 문자열 최대 길이 업데이트
mn_len = min(mn_len, cur_len); // mn_len: 문자열 최소 길이 업데이트

Choose a reason for hiding this comment

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

슬라이딩 윈도우 활용이 너무 좋네요👍👍


if(mx_len == 0 || mn_len == MAX) {
cout << "-1\n";
}

Choose a reason for hiding this comment

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

if문 내에서는 둘 중 한 가지만 확인해주셔도 될 것 같네요😊

mn_len = min(mn_len, cur_len); // mn_len: 문자열 최소 길이 업데이트
}
}
}

Choose a reason for hiding this comment

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

해당 부분은 테스트 케이스마다 계속해서 사용되는 부분이네요! 메인을 최대한 간단하게 해주기 위해 해당 부분을 함수화하면 어떨까요?😊

int cur_alphaBet = W[i]-'a';
cnt[cur_alphaBet]++; // 알파벳 문자별로 등장한 횟수를 저장해주는 작업
alpha_loc[cur_alphaBet].push_back(i); // 알파벳 문자별로 등장한 인덱스의 위치 값을 저장해주는 작업
}

Choose a reason for hiding this comment

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

이 부분도 함수화할 수 있을 것 같습니다😉

int T;
cin >> T;
while(T--){
string W;

Choose a reason for hiding this comment

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

이 부분도 마찬가지로 변수는 스네이크 표기법을, 상수는 대문자 표기법을 사용해주시면 좋을 것 같네요:)

Copy link

@kwakrhkr59 kwakrhkr59 left a comment

Choose a reason for hiding this comment

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

안녕하세요 수정님~ 13422번 질문 관련하여 답변 남겨드렸습니다! 참고하셔서 해결해보시고 그래도 어려움이 있으시다면 언제든 다시 질문 남겨주세요😊

for(int i = 0; i < N; i++){
cin >> home[i];
}
psum[0] = home[0];

Choose a reason for hiding this comment

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

누적합에서 핵심은 i번째 원소부터 jj번째 원소까지의 합은 sum[j] - sum[**i - 1**]라는 거였죠! 그런데 psum[0]에 첫번재 원소값을 저장해주면 위에서 psum[e] - psum[s-1]를 계산할 때 잘못된 인덱스를 가리킬 위험이 있네요! 이 부분 먼저 수정해주시면 될 것 같습니다😀


int solve(vector<int> &home, vector<int> &psum, int &N, int &M, int &K) {
int answer = 0;
int s = 0, e = M-1;

Choose a reason for hiding this comment

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

이부분도 마찬가지로 올바른 인덱스를 가리키고 있을지 확인해주세요!

int solve(vector<int> &home, vector<int> &psum, int &N, int &M, int &K) {
int answer = 0;
int s = 0, e = M-1;
while(s <= e && e < N+M) {

Choose a reason for hiding this comment

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

이 문제의 핵심은 숨어있는 코너케이스를 발견할 수 있느냐이죠! N과 M이 같아졌을 때 결과값은 1 또는 0이어야 하는데 이 부분을 따로 예외처리하지 않아주면 똑같은 연산을 여러 번 반복할 위험이 있네요😥 이부분까지 처리해주시면 잘 돌아갈 것 같습니다😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants