inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

2-F

모든 테스트 케이스랑 반례 찾아서 넣어도 맞게 나옵니다

98

요가인

작성한 질문수 35

0

안녕하세요!

오랜만에 다시 코테를 푸는데 맞왜틀이 나와서 질문 드립니다!

#include <iostream>
using namespace std;

int N, M, J;
int l, r, cnt;

int main(){
    cin >> N >> M >> J;
    
    // 초기화
    l = 1; r = M; cnt = 0;
    
    for (int i = 0; i < J; i++){
        int apple;
        cin >> apple;

        // 범위 안이라서 움직일 필요 없다.
        if (apple >= l && apple <= r) continue;
        
        // 왼쪽에 가까우면 왼쪽으로 이동 오른쪽에 가까우면 오른쪽으로 이동
        int leftLength = abs(l - apple);
        int rightLength = abs(r - apple);
        bool isLeft = leftLength < rightLength ? true : false;

        if (isLeft){
            l -= leftLength;
            r -= leftLength;
            cnt += leftLength;
        }
        else{
            l += rightLength;
            r += rightLength;
            cnt += rightLength;
        }    
    }

    cout << cnt;

    return 0;
}

제가 만든 로직대로라면 절대로 경계값을 벗어날 수가 없습니다.
왜냐하면 문제에서 "각 사과는 N칸중 한 칸의 상단에서 떨어지기 시작하며" 라고 주어져 있기 때문입니다.

67%에서 틀렸다고 나옵니다..!

c++ 코딩-테스트

답변 1

1

큰돌

안녕하세요 가인님 ㅎㅎ

코드를 보시면 거리를 기반으로 판단하게 되는데요. 만약 M이 1일 때 저 로직은 깨지게 됩니다.

isLeft 변수가 “어느 쪽으로 이동 거리가 더 짧은지”만 알려줄 뿐, 사과가 바구니의 왼쪽에 떨어졌는지 오른쪽에 떨어졌는지를 직접 알려주진 않습니다.

가인님 코드를 보시면

  • leftLength = abs(l - apple) 은 사과와 바구니 왼쪽 끝 사이의 거리

  • rightLength = abs(r - apple) 은 사과와 오른쪽 끝 사이의 거리

을 상징하고 두 값 중 작은 쪽이 “짧은 이동”이긴 하지만,

  • 사과가 이미 바구니 범위 (l ≤ apple ≤ r) 안에 있다면 이동이 전혀 필요 없고,

  • 사과가 바구니의 왼쪽 밖에(apple < l) 있으면 반드시 왼쪽으로 가야 하며,

  • 사과가 오른쪽 밖에(apple > r) 있으면 반드시 오른쪽으로 가야 합니다.

따라서 만약 abs를 쓸거면 다음과 같이 써야 합니다.

#include <iostream>
#include <cmath>
using namespace std;

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

    int N, M, J;
    cin >> N >> M >> J;

    int l = 1;
    int r = M;
    long long cnt = 0;

    for (int i = 0; i < J; i++) {
        int apple;
        cin >> apple;

        int leftLength  = abs(l - apple);
        int rightLength = abs(r - apple);
        bool isLeft     = leftLength < rightLength;

        if (apple < l || apple > r) {
            int diff = isLeft ? leftLength : rightLength;

            if (apple < l) {
                diff = leftLength;
                isLeft = true;
            } else if (apple > r) {
                diff = rightLength;
                isLeft = false;
            }

            cnt += diff;
            if (isLeft) {
                l -= diff;
                r -= diff;
            } else {
                l += diff;
                r += diff;
            }
        }
    }

    cout << cnt;
    return 0;
}

 

후... 여러번 고민하다 알아냈네요 ㅎㅎ

 


 

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

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

감사합니다.

강사 큰돌 올림.


0

요가인

아.. 첫번째 테스트 케이스가 운좋게 값이 맞아서 통과했던 거네요..
감사합니다
저도 한참 찾았는데 뭐가 문젠지 몰랐는데 이해했습니다~!

2-I) 왜 이 문제가 그래프이론 카테고리에 있는지 잘 모르겠습니다.

0

18

2

2주차 개념#12 트리 순회

0

20

2

백준사이트가 종료된다고 합니다.

0

234

2

백준 서비스 종료

9

742

1

sk 하이닉스 코테 대비

0

356

2

3-G 최댓값 질문

0

50

1

모듈러 연산 값이 10이 아닌 경우도 있지 않나요?

0

82

2

3-I 코드 질문드립니다.

0

61

2

3-N 질문 있습니다.

0

66

2

학습방법

0

100

2

4-H 질문 있습니다 (코드 리뷰)

0

66

2

코딩테스트 어디까지 준비해야 하는지 질문이 있습니다.

0

164

2

2-O 반례가 무엇일지 어떤 부분이 틀렸는지 잘 모르겠습니다.

0

69

2

2주차 개념 #4-2. 인접행렬 질문있습니다.

0

63

2

1-A 문제풀이 후 궁금한 점이 생겨서 질문드립니다.

0

49

2

조합 재귀 풀이 확인 해주시면 감사하겠습니다.

0

67

2

함수별 시간복잡도

0

72

2

3-h 질문입니다.

0

49

1

안녕하세요 선생님. 시간 복잡도 4번 질문있습니다.

0

52

2

1-I 문제 질문 드립니다.

0

76

2

2-P 질문입니다.

0

56

1

mac에서 시작하기 관련

0

88

2

5-Q 질문

0

63

2

풀이 코드 질문

0

64

2