일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 빅오 표기법
- dfs
- 자바의정석
- 백준
- BFS
- java
- 백준알고리즘
- 무료개발강의
- 알고리즘
- 알고리즘공부
- 다이나믹 프로그래밍
- 백트래킹
- 코딩공부
- 무료코딩강의
- 백준자바
- 개발공부
- 자바
- ☆
- Java개념
- 자바공부
- ★
- 시간 복잡도
- 자바의정석연습문제풀이
- 브루트포스
- 백준단계별로풀어보기
- 동적계획법
- 자바개념
- dp
- 백준9단계
- 자바의정석연습문제
- Today
- Total
더 많이 실패하기
공부 201일차: 백준 14226번 이모티콘 자바 java 본문
14226 이모티콘
https://www.acmicpc.net/problem/14226
14226번: 이모티콘
영선이는 매우 기쁘기 때문에, 효빈이에게 스마일 이모티콘을 S개 보내려고 한다. 영선이는 이미 화면에 이모티콘 1개를 입력했다. 이제, 다음과 같은 3가지 연산만 사용해서 이모티콘을 S개 만
www.acmicpc.net
백준 14226번 문제 이모티콘
문제
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
2 초 | 512 MB | 21564 | 8130 | 5389 | 34.125% |
문제
영선이는 매우 기쁘기 때문에, 효빈이에게 스마일 이모티콘을 S개 보내려고 한다.
영선이는 이미 화면에 이모티콘 1개를 입력했다. 이제, 다음과 같은 3가지 연산만 사용해서 이모티콘을 S개 만들어 보려고 한다.
- 화면에 있는 이모티콘을 모두 복사해서 클립보드에 저장한다.
- 클립보드에 있는 모든 이모티콘을 화면에 붙여넣기 한다.
- 화면에 있는 이모티콘 중 하나를 삭제한다.
모든 연산은 1초가 걸린다. 또, 클립보드에 이모티콘을 복사하면 이전에 클립보드에 있던 내용은 덮어쓰기가 된다. 클립보드가 비어있는 상태에는 붙여넣기를 할 수 없으며, 일부만 클립보드에 복사할 수는 없다. 또한, 클립보드에 있는 이모티콘 중 일부를 삭제할 수 없다. 화면에 이모티콘을 붙여넣기 하면, 클립보드에 있는 이모티콘의 개수가 화면에 추가된다.
영선이가 S개의 이모티콘을 화면에 만드는데 걸리는 시간의 최솟값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 S (2 ≤ S ≤ 1000) 가 주어진다.
출력
첫째 줄에 이모티콘을 S개 만들기 위해 필요한 시간의 최솟값을 출력한다.
예제 입력 1
2
예제 출력 1
2
예제 입력 2
4
예제 출력 2
4
예제 입력 3
6
예제 출력 3
5
예제 입력 4
18
예제 출력 4
8
과정 생각해보기 & 오답
냅다 틀린 과정부터.. 완성을 못했으니 오답이라고도 못한다
생각 자체가 bfs를 제대로 이해한 건 맞는지 의심되기도 하고.. 부끄럽지만 오늘은 남긴다..^^
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import java.io.*;
import java.util.*;
public class Main {
static int s;
static int[] visited = new int[1001]; // 인덱스: 현재 화면 이모티콘 개수, 값: 걸린 시간
static Stack<Integer> clipboard = new Stack<>(); // 클립보드 생성
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
s = Integer.parseInt(br.readLine());
bfs();
System.out.println(visited[s]);
}
static void bfs() {
Queue<Integer> q = new LinkedList<>();
q.add(1); // 이모티콘 1개에서 시작
while(!q.isEmpty()) {
int now = q.poll();
if(now == s) {
return;
}
for(int i = 0; i < 3; i++) { // 경우의 수 3개
int next = 0;
if(i == 0) {
if(!clipboard.isEmpty()) { // 클립보드에 있다면
next = clipboard.pop(); // 화면의 이모티콘은 그 숫자
}
}else if(i == 1) {
clipboard.clear(); // 이전 클립보드 초기화
clipboard.push(now); // 현재 이모티콘 개수 스택에 넣기
next = now;
}else {
next = now - 1;
}
if(next < 1 || next > 1000) {
continue;
}
if(visited[next] == 0) {
q.add(next);
// 화면의 이모티콘 개수는 다시 방문할 수 있으므로 visited[next]=visited[now]+1를 쓰기도 애매..
}
}
}
}
}
|
cs |
난 너무 지난 문제 해결 방안을 그대로 쓰려는 경향이 짙은 것 같다.. 고쳐야지..
완전히 막혀서 참고하게 된 건 이 블로그(다른 블로그들도 비슷하게 푼 듯하다)
핵심은
1. 방문 여부를 2차원 배열로 확인 (클립보드, 화면)
2. 이모티콘 class를 따로 정의해서 사용 (클립보드, 화면, 시간)
지금까지 문제들을 보아하니 횟수를 구할 거면 타입을 따로 정의하는 게 베스트인 듯
(그 전의 나는 한 번만 구하는 거라 굳이 이렇게 만들지 않아도 된다고 생각했다.. 클립보드까지 있으니까 같이 데리고 가야 한다는 걸 고려했어야 했는데..)
정답 인정 코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
import java.io.*;
import java.util.*;
public class Main {
static int s;
static boolean[][] visited = new boolean[1001][1001]; //[클립보드][화면]
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
s = Integer.parseInt(br.readLine());
bfs();
}
static void bfs() {
Queue<Emoticon> q = new LinkedList<>();
q.add(new Emoticon(0, 1, 0));
visited[0][1] = true; // 클립보드0 모니터1 방문처리
while(!q.isEmpty()) {
Emoticon now = q.poll();
if(now.screen == s) {
System.out.println(now.time);
return;
}
// 화면의 이모티콘을 클립보드에 저장
q.add(new Emoticon(now.screen, now.screen, now.time+1));
// 클립보드의 이모티콘을 화면에 붙여넣기
// 현재 클립보드에 무언가 저장되어 있고 & 클립보드를 붙여넣기했을 때 원하는 개수를 넘지 않으며 & 아직 방문하지 않음
if(now.clipboard != 0 && now.screen + now.clipboard < s+1 && !visited[now.clipboard][now.screen+now.clipboard]) {
q.add(new Emoticon(now.clipboard, now.screen+now.clipboard, now.time+1));
visited[now.clipboard][now.screen+now.clipboard] = true; // 방문 처리
}
// 화면의 이모티콘 중 1개 지우기
// (조건: s >= 2) s가 될 수 있는 범위이고 && 아직 방문하지 않음
if(now.screen-1 > 1 && !visited[now.clipboard][now.screen-1]) {
q.add(new Emoticon(now.clipboard, now.screen-1, now.time+1));
visited[now.clipboard][now.screen-1] = true;
}
}
}
}
class Emoticon{
int clipboard = 0;
int screen = 0;
int time = 0;
Emoticon(int clipboard, int screen, int time){
this.clipboard = clipboard;
this.screen = screen;
this.time = time;
}
}
|
cs |
'알고리즘 > 백준' 카테고리의 다른 글
공부 203일차: 백준 1261번 알고스팟 자바 java (0) | 2023.02.18 |
---|---|
공부 202일차: 백준 13549번 숨바꼭질 3 자바 java (0) | 2023.02.17 |
공부 200일차: 백준 13913번 숨바꼭질 4 자바 java (0) | 2023.02.15 |
공부 199일차: 백준 12851번 숨바꼭질 2 자바 java (0) | 2023.02.14 |
공부 198일차: 백준 1697번 숨바꼭질 자바 java (0) | 2023.02.13 |