일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 브루트포스알고리즘
- 프로그래머스연습문제
- 자료구조
- 정수론
- 백준알고리즘
- 구현
- 해시를사용한집합과맵
- 이진탐색
- 논문리뷰
- 백준
- 큐
- 이분탐색
- C언어
- SQL
- Image Classification
- 그리디
- 그리디알고리즘
- 소수판정
- C++
- 프로그래머스코딩테스트
- 문자열
- 프로그래머스
- C
- 사칙연산
- MySQL
- 수학
- 프로그래머스sql
- 정렬
- 다이나믹프로그래밍
- 논문구현
- Today
- Total
초보 개발자의 이야기, 릿허브
[C++] 백준 1449번 수리공 항승 본문
1. 문제이해
https://www.acmicpc.net/problem/1449
물이 새는 곳의 개수(N)와 위치, 테이프의 길이(L)가 주어진다.
테이프를 이용해서 물이 새는 곳을 막으려고 할 때, 필요한 테이프의 개수를 출력하는 것이 목표이다.
2. 문제풀이
물이 새는 곳을 테이프로 막으려고 할 때, 필요한 테이프의 개수를 구하는 것이 목표이다.
예제 입력 1을 보자.
물이 새는 곳의 개수(N)는 4, 테이프의 길이(L)는 2
물이 새는 곳의 위치는 각각 1, 2, 100, 101 이다.
테이프의 길이가 2 이므로, 물이 새는 위치인 1, 2 를 1개의 테이프로 막을 수 있다.
그 다음 100, 101 을 1개의 테이프로 막을 수 있다.
이렇게 테이프로 물이 새는 위치를 막으려면 총 2개의 테이프가 필요하다.
위와 같이 테이프의 길이와 물이 새는 곳의 위치에 따라 필요한 테이프의 개수가 틀려진다.
여기서 고려해야 할 점은, 테이프를 최대로 붙일 수 있는 지점이다.
예제 입력 1에서, 테이프의 길이는 2이므로,
테이프를 붙이는 시작 위치인 1부터 시작해, 2, 100, 101 중 2까지만 붙일 수 있다.
처음으로 (테이프의 길이 <= 시작 지점부터 다른 누수 지점 까지의 거리) 가 되면,
해당 위치 전까지만 테이프를 붙일 수 있기 때문이다.
따라서, 예제 입력에서 처음으로 시작지점 ~ 누수지점 까지의 거리가 테이프의 길이를 넘어가는 지점은
(테이프의 길이(2) < 다른 누수지점(100) 과 시작 지점(1) 사이의 거리(99)) 이기 때문에,
해당 지점 이전인 2 까지만 테이프를 붙일 수 있게 된다.
따라서, 코드를 짤 때 적용해야 할 알고리즘은 다음과 같다.
1. 누수 지점을 오름차순 정렬 (누수 지점이 뒤죽박죽 입력되는 경우도 있기 때문)
2. (테이프의 길이 <= 시작 지점부터 다른 누수 지점(A) 까지의 거리) 가 되면,
필요한 테이프의 개수 + 1
테이프를 다시 붙이게 되는 시작 위치를 재설정
(새로운 시작 위치는 위의 다른 누수 지점(A)으로 한다.)
3. 2의 작업을 반복.
단, 마지막 테이프의 개수는 세어지지 않으므로 테이프의 개수 + 1 후 출력
3. 소스코드
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N; // 물이 새는 곳의 개수
int L; // 테이프의 길이
int location[1000]; // 물이 새는 곳의 위치
int start; // 각 테이프의 시작 위치
int tape = 0; // 필요한 테이프의 개수
cin >> N >> L;
for (int i = 0; i < N; i++) {
cin >> location[i];
}
// 물이 새는 위치를 오름차순 정렬
sort(location, location + N);
// 시작 위치를 맨 처음 누수 위치로 설정
start = location[0];
for (int i = 1; i < N; i++) {
// 테이프의 길이가 모자라게 되면
if (L <= location[i] - start) {
// 해당 지점 전까지 테이프를 사용했으므로 값 증가
tape++;
// 테이프가 부족한 지점부터 시작위치 재설정
start = location[i];
}
}
// for문에서 마지막에 붙인 테이프는 세지 않았으므로 + 1
cout << tape + 1;
return 0;
}
2. 문제풀이에서 도출한 알고리즘을 이용한 소스코드는 위와 같다.
물이 새는 위치의 개수 위치, 테이프의 길이를 입력받는다.
물이 새는 위치를 오름차순으로 정렬 후, 맨 처음 위치를 테이프를 붙이는 시작 위치로 정한다.
그리고, for문을 통해 (테이프의 길이 <= 시작 지점부터 다른 누수 지점(A) 까지의 거리) 가 되면,
필요한 테이프의 개수 + 1, 테이프를 다시 붙이게 되는 시작 위치를 재설정
한다.해당 과정을 반복 후, 필요한 테이프의 개수(tape + 1)를 출력한다.
어쩌다보니 그리디 알고리즘 풀이가 제일 많아 보이는 것 같은데..🤔
다른 유형 문제들도 많이 풀어 포스팅해보도록 해야지😤
'코딩테스트 > 📗 백준 (BOJ)' 카테고리의 다른 글
[C++] 백준 1431번 시리얼 번호 (0) | 2022.01.12 |
---|---|
[C++] 백준 1105번 팔 (0) | 2022.01.08 |
[C++] 백준 1541번 잃어버린 괄호 (0) | 2022.01.04 |
[C++] 백준 2884번 알람 시계 (0) | 2021.12.16 |
[C++] 백준 2588번 곱셈 (0) | 2021.12.15 |