코딩테스트/백준
[Gold V][JAVA] 2877번: 4와 7
lakedata
2025. 3. 21. 00:42
[Gold V] 4와 7 - 2877
성능 요약
메모리: 14252 KB, 시간: 104 ms
분류
구현, 수학
문제 설명
창영이는 4와 7로 이루어진 수를 좋아한다. 창영이가 좋아하는 수 중에 K번째 작은 수를 구해 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 K(1 ≤ K ≤ 109)가 주어진다.
출력
첫째 줄에 창영이가 좋아하는 숫자 중 K번째 작은 수를 출력한다.
풀이과정
1자리의 47수: 2 # 4, 7
2자리의 47수: 4 # 44, 47, 74, 77
3자리의 47수: 8 # 444, 447, 474, 477, 744, 747, 774, 777
4자리의 47수: 16 # 4444, 4447, 4474, 4477, 4744, 4747, 4774, 4777,
# 7444, 7447, 7474, 7477, 7744, 7747, 7774, 7777
bfs로 풀려고 했는데 K(1 ≤ K ≤ 109)범위로 큐에 모든 숫자를 넣는 방식은 메모리 초과를 초래합니다.
아래 코드는 잘못된 범위와 시간을 고려하지 않는 코드입니다.
import java.util.*;
import java.io.*;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long k = Long.parseLong(br.readLine()); // K번째 숫자
Queue<String> que = new LinkedList<>();
que.add("4");
que.add("7");
long count = 0;
while(!que.isEmpty()) {
String current = que.poll();
count++;
// K번째 숫자를 찾으면 종료
if (count == k) {
System.out.println(current);
return;
}
// "4"와 "7"을 이어 붙인 새로운 숫자들을 큐에 추가
que.add(current + "4");
que.add(current + "7");
}
}
}
해결 방법
- 4와 7을 0과 1로 바꾸어 2진수와 같이 생각합니다.
- 입력한 수에 1을 더한 뒤 2진수로 바꾸면 규칙을 찾을 수 있습니다.
- n번째 수를 찾으려면 n+1을 이진수로 바꾸고 가장 앞자리를 생략합니다.
❌ 0부터 시작하면 어떻게 될까?
0 | 0 | 4 | ❌ (없어야 함) |
1 | 1 | 7 | ❌ (4여야 함!) |
2 | 10 | 4 7 | ❌ (7여야 함!) |
3 | 11 | 7 7 | ❌ (44여야 함!) |
❌ +1을 하지 않고 변환해볼까?
1 | 1 | 7 | ❌ (4여야 함) |
2 | 10 | 4 7 | ❌ (7여야 함) |
3 | 11 | 7 7 | ❌ (44여야 함) |
✅ +1을 하고 변환하면?
1 | 2 | 10 | 4 7 | 4 ✅ |
2 | 3 | 11 | 7 7 | 7 ✅ |
3 | 4 | 100 | 4 4 4 | 44 ✅ |
정답 코드
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s = Integer.toBinaryString(Integer.parseInt(br.readLine())+1).replace('0','4').replace('1', '7');
for(int i=1;i<s.length();i++)
bw.write(s.charAt(i));
bw.flush();
bw.close();
}
}