강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

K케이님의 프로필 이미지
K케이

작성한 질문수

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

5-M

5-M 12100 맞왜틀팁 질문드립니다.

해결된 질문

작성

·

31

0

안녕하세요 선생님!

선생님의 해설 코드를 본 뒤, 제 방식대로 코드를 구현해봤어요. struct 없이 구현했고, vector를 사용했다는 점이 가장 큰 차이점이에요.

https://www.acmicpc.net/source/share/76924786b7cb49bd8214270312660074

 

다만 해당 코드가 계속 '틀렸습니다'가 뜨는데 그 원인을 명확하게 모르겠어요. 혹시 도와주실 수 있으실까요?

답변 2

1

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 케이님 ㅎㅎ

정말 잘 짜셨네요 ㅎㅎ

후 너무 좋은 코드라서 디버깅하는데 오래걸렸습니다. 틀린점을 찾기가 쉽지가 않더라구요.

for(int k = 0; k < (int)v.size() - (int)temp.size(); k++) temp.push_back(0);

이 코드 때문에 틀렸습니다. temp 에 push하면서 temp사이즈가 변경되면서 사이드 이펙트가 발생되겠죠?

제가 다듬은 + 주석 달은 코드입니다. 참고부탁드립니다.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int n;
int ret;

void countMaxValue(const vector<vector<int>> &v) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            ret = max(ret, v[i][j]);
        }
    }
}

void rotate90(vector<vector<int>> &v) {
    int y = v.size();
    int x = v[0].size();
    vector<vector<int>> temp(x, vector<int>(y)); 
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            temp[i][j] = v[j][x - 1 - i];
        }
    }
    //resize부분은 없어도 됩니다.
    v = temp;
}

void moveUp(vector<vector<int>> &v) {
    // n x n 보드라는 가정이 항상 성립하므로 n 사용해도 됩니다. 
    for (int j = 0; j < n; j++) {
        vector<int> temp;
        bool canMerge = true;

        for (int i = 0; i < n; i++) {
            if (v[i][j] == 0) continue;

            if (!temp.empty() && temp.back() == v[i][j] && canMerge) {
                // back을 써도 됩니다.
                temp.back() *= 2;
                canMerge = false;   
            } else {
                temp.push_back(v[i][j]);
                canMerge = true;
            }
        }
   
        while ((int)temp.size() < n) temp.push_back(0);
        for (int i = 0; i < n; i++) {
            v[i][j] = temp[i];
        }
    }
}

void go(int moveCnt, const vector<vector<int>> &v) {
    if (moveCnt == 5) {  
        countMaxValue(v);
        return;
    }

    vector<vector<int>> localV = v;
	// 너무 좋습니다.
    for (int i = 0; i < 4; i++) {
        vector<vector<int>> next = localV;
        moveUp(next);             
        go(moveCnt + 1, next);     
        rotate90(localV);          
    }
}

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

    cin >> n;
    vector<vector<int>> board(n, vector<int>(n));
    // 이렇게 받는게 더 깔끔합니다.  
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> board[i][j];
        }
    }

    go(0, board);
    // go에서 4방향으로 호출하고 있는데 처음부터 4방향을 호출할 필요는 없습니다.
    cout << ret << "\n";
    return 0;
}

 


 

또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.

K케이님의 프로필 이미지
K케이
질문자

칭찬 감사합니다 ㅎㅎ 저도 틀린 점 찾기 너무 어려웠는데 감사합니다 !!

다만 달아주신 주석 보고 여쭤보고 싶은 질문이 하나 더 생겼어요!

 

혹시 //resize부분은 없어도 됩니다. 라고 해주신 부분은 n*n 크기라는 가정이 있어서인게 맞나요? (저는 범용적인 코드를 작성해보고 싶어서, 일부러 직사각형이라고 가정하고 코드를 작성했거든요!)

큰돌님의 프로필 이미지
큰돌
지식공유자

네네 맞습니다. 직사각형일 경우 resize 필요, 크기 정해진 경우 필요없습니다.

0

안녕하세요, 인프런 AI 인턴입니다.

K케이님이 작성하신 코드를 확인하면서 ‘맞왜틀’(정답일 것 같은데 틀렸다) 문제의 가능성을 고려해야 할 것 같습니다. 코드가 틀렸다고 나오는 일반적인 이유 중 몇 가지를 짚어 보겠습니다:

  1. 경계 조건과 초기 설정: 문제에서 주어진 입력의 경계 조건이나 초기 설정이 잘못되어 있을 가능성이 있습니다. 특히, 움직임의 방향 변화에 따른 벡터의 업데이트 과정에서 실수가 발생할 수 있습니다.

  2. 알고리즘의 논리적 오류: 방향 전환 및 블록 병합 과정에서 예상치 못한 오류가 생길 수 있습니다. 간혹 element들을 병합하거나 공간을 정리하는 과정에서 논리적 오류가 생겨 결과가 예상과 달라질 수 있습니다.

  3. 테스트 케이스: 다양한 테스트 케이스를 바탕으로 프로그램을 디버깅해보세요. 특히 엣지 케이스에서 코드가 어떻게 작동하는지 확인해 보시면 도움이 될 것입니다.

  4. 벡터 사용 방식: struct 없이 벡터를 사용하셨다고 하셨는데, 벡터의 동작 및 요소 추가/삭제 혹은 정렬 과정에서 문제가 발생했을 수 있습니다.

이 밖에도 유사한 문제를 겪고 해결한 질문들을 참고하실 수 있습니다:

K케이님의 상황에서 특히 벡터의 작동을 확인해보시고, 위의 유사한 질문 링크를 바탕으로 추가적인 힌트를 얻으시면 좋겠습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

K케이님의 프로필 이미지
K케이

작성한 질문수

질문하기