[백준] 2869번 : 달팽이는 올라가고 싶다 (C++)

2024. 3. 7. 18:10·Programming/C++ - 백준
반응형


문제


풀이

 이 문제를 풀면서 참 많은 고난이 있었다.. 세 번째 풀이만에 성공했고.. 문제를 풀면서 화난 치와와가 된 기분을 느꼈다..

첫 번째 코드 - 실패 

 ➡ 시간복잡도: O(n), while문 사용

 

처음에는 단순하게 A만큼 증가하고, B만큼 감소하는 while문을 만들어 높이 변수 height가 V에 도달하면 break 되도록 했다.

하지만, 시간 초과가 발생했다.

 

//첫 번째 시도_ O(n), 시간초과

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

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
    
	int A, B, V, height = 0, day = 0;
	cin >> A >> B >> V;

	while (1) {
		height += A;
		++day;
		if (height >= V) {
			break;
		}
		height -= B;
	}

	cout << day;

	return 0;
}

 

 

 

 - 시간 초과 이유: 반복문을 사용해, O(n)의 시간복잡도를 갖는다. 따라서, 시간이 너무 오래 걸린다.

 

이 문제는 시간 제한이 0.25초이기 때문에 반복문을 사용하면 시간이 초과된다.

예를 들어, A = 1000, B = 999, V = 1000000 인 경우라면, 아래처럼 999001일이 걸린다.

만약, 반복문을 사용하면 오르락 내리락을 대략 999000번 반복하므로 시간 초과가 발생하는 것이다.

추가로, 이 코드에서는 (A >= V)인 조건도 고려하지 않았다.

  

 

 


두 번째 코드 - 실패 

 ➡ 시간복잡도: O(n), while문 사용

 

식으로 풀어야겠다고 생각하여, (A - B)씩 증가하는 것으로 접근해 풀었으나 결론적으로는 또 반복문을 써서 시간초과가 발생했다. 이 코드도 (A >= V)인 조건을 추가하지 않았지만, 다른 반례들은 모두 통과했다. 그냥 더 복잡하고 똑같이 시간초과가 나는 코드를 만들어냈다..

 

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

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

	int A, B, V, height = 0, day = 0, before, semibefore;
	cin >> A >> B >> V;

	before = A - 2 * B;
	semibefore = A - B;
	while (1) {
		height += (A - B);
		day++;
		cout << day << endl;
		if (height >= V) {
			height -= before;
			day--;
			cout << day << "   ";
			while (1) {
				if (height <= V) {
					break;
				}
				height -= semibefore;
				day--;
				cout << day << "   ";
			}
			break;
		}
	}

	cout << day;

	return 0;
}

 

따라서, 마지막 풀이에는 절대 반복문을 쓰지 않기로, 시간 복잡도 O(1)로 풀기로 다짐하고 다시 도전했다.

 


세 번째 코드 - 성공  

 ➡ 시간복잡도: 드디어 O(1)!

 

 조건을 세 가지로 나누었다.

 

 1. A가 V보다 크거나 같은 경우 - 달팽이가 하루만에 나무를 올라가므로, 항상 하루 소요

	if (A >= V) {
		cout << "1";
	}

 

 

 2.  A가 V보다 작은 경우: 나무의 높이인 V에서 달팽이가 일어나있는 동안 올라가는 높이인 A를 뺀 값을 활용했다.

 

 2-1. 만약, (V - A)에서 (A - B)를 나눈 나머지가 0이라면, (A - B) x ( Day ) + A = V 일 것이다.

예를 들어, A = 3, B = 2, V = 7 인 경우라면, (3 - 2) x ( Day ) + 3 = 7이다.

Day = 4지만, A만큼 올라간 하루를 더 추가해주어야 한다.

 

	else if ((V - A) % (A - B) == 0) { // 나머지 == 0이라면, 딱 A만큼 더 가면 V에 도달하므로 +1을 해준다.
		cout << ((V - A) / (A - B) + 1);
	}

 

 

 2-2. 만약, (V - A)에서 (A - B)를 나눈 나머지가 0이 아니라면, (A - B) x ( Day ) + (A - B) + (A보다 적은 길이) = V 이다.

Day에서, (A - B)만큼과 (A보다 작은 수)만큼 더 올라가므로 이틀을 더 추가해주어야 한다.

 

	else if ((V - A) % (A - B) != 0) { // 나머지 != 0이라면, (A-B)만큼 한 번더 올라간 후 A보다 작은 높이가 남은 것이므로 +2
		cout << ((V - A) / (A - B) + 2);
	}

정답 코드

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

int main() {
	int A, B, V;
	cin >> A >> B >> V;

	if (A >= V) {
		cout << "1";
	} 
	else if ((V - A) % (A - B) == 0) {	// 나머지 == 0이라면, 딱 A만큼 더 가면 V에 도달하므로 +1을 해준다.
		cout << ((V - A) / (A - B) + 1);
	}
	else if ((V - A) % (A - B) != 0) {	// 나머지 != 0이라면, (A-B)만큼 한 번더 올라간 후 A보다 작은 높이가 남은 것이므로 +2
		cout << ((V - A) / (A - B) + 2);
	}


	return 0;
}

결과

 

반응형
저작자표시 (새창열림)

'Programming > C++ - 백준' 카테고리의 다른 글

[백준] 10828번 : 스택 (C++)  (0) 2024.03.11
[백준] 2798번 : 블랙잭 (C++)  (1) 2024.03.10
[백준] 5597번 : 과제 안 내신 분..? (C++)  (0) 2024.03.05
[백준] 7568번 : 덩치 (C++) + pair 클래스  (0) 2024.03.03
[백준] 1978번 : 소수 찾기 (C++)  (1) 2024.02.21
'Programming/C++ - 백준' 카테고리의 다른 글
  • [백준] 10828번 : 스택 (C++)
  • [백준] 2798번 : 블랙잭 (C++)
  • [백준] 5597번 : 과제 안 내신 분..? (C++)
  • [백준] 7568번 : 덩치 (C++) + pair 클래스
지구코드
지구코드
IT를 공부하고 있는 지구의 코딩공간입니다!
  • 지구코드
    지구의 코딩공간
    지구코드
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 개발 기록
      • [프디아] 파이널 프로젝트
      • Back-end
        • Spring
        • Django
      • Programming
        • 알고리즘
        • C++ - 백준
      • Cloud
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    MSA
    dp
    알파코캠퍼스
    시간초과
    EC2
    별 찍기
    프로디지털아카데미
    알파코
    AWS
    Cloud
    구조체 벡터
    백준
    fill 함수
    정렬
    C++
    다이내믹 프로그래밍
    awscloudclubs
    프디아
    KDT교육
    신한투자증권
    k디지털트레이닝
    부트캠프
    이진탐색
    큐
    edgelocation
    시간복잡도
    슬라이딩윈도우
    binary_search
    피보나치 수
    부분 문자열 추출
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.3
지구코드
[백준] 2869번 : 달팽이는 올라가고 싶다 (C++)
상단으로

티스토리툴바