반응형
아무리 생각해도 논리는 맞는 것 같은데 자꾸 오류가 떠서 이 문제만 하루는 잡고 있었다..
논리오류가 아닌 코드오류였던 것에 반성하자
풀이과정
가장 큰 중요도를 기준으로 맨 앞의 문서의 중요도가 낮으면 빼낸 후 뒤로 보내기
중요한 것은 같은 중요도를 가진 문서도 많을 수 있다는 것. >> 원하는 문서의 위치를 저장하여 위치가 맨 앞일 때가 답임
가장 큰 중요도도 계속해서 바뀌기 때문에 중요도를 넣을 배열도 생성.
문제를 풀고 얻어낸 점
BufferedReader와 StringTokenizer에 대한 이해
if-else문의 논리구조
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Queue_Q1966 {
static int answerImportance; // 구해야 할 문서의 중요도
static int answerIndex; //구해야 할 문서의 위치
static int Top; //현재 가장 큰 중요도
static int indexOfTop; // 현재 가장 큰 중요도의 배열리스트 내의 위치
static int result; // 해당 문서가 처리되는 순서 (답)
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine()); //테스트케이스 입력
for(int t = 1; t <= T; t++) { //테스트케이스만큼 반복
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken()); //queue의 크기 입력
int M = Integer.parseInt(st.nextToken()); //찾아야 하는 문서의 위치 (인덱스)
ArrayList<Integer> arrList = new ArrayList<>(); // 중요도 넣을 배열리스트 생성
Queue<Integer> queue = new LinkedList<>(); //큐 선언
st = new StringTokenizer(br.readLine()); //왜 또 선언해줘야 하는지?
int importance;
for(int n = 0; n < N; n++) {
importance = Integer.parseInt(st.nextToken()); //중요도 입력
queue.offer(importance); // 큐 삽입
arrList.add(n, importance);
if(n == M) {
answerImportance = importance; //구해야 할 문서의 중요도
answerIndex = n; //구해야 할 문서의 위치
}
}
arrList.sort(Comparator.naturalOrder()); //배열리스트 오름차순 정리
indexOfTop = N - 1; // 가장 큰 중요도의 위치 초기화 (오름차순이니까 맨 끝)
Top = arrList.get(indexOfTop); // 현재 가장 큰 중요도
result = 0;
//System.out.println(queue);
//System.out.println("가장 큰 중요도" + Top);
//System.out.println("구해야 하는 중요도 " + answerImportance);
while(!queue.isEmpty()) { // 큐가 비어있지 않는 동안
int num;
if(answerImportance < Top) { //구해야 하는 중요도가 가장 큰 중요도가 아닐 때
if(queue.peek() == Top) {
queue.remove();
Top = arrList.get(--indexOfTop); // 가장 큰 중요도 바꿔줌. indexOfTop--은 안됨 왜?
//System.out.println("삭제 후 가장 큰 중요도는 " + Top);
if(answerIndex == 0)
answerIndex = queue.size() - 1;
else
answerIndex--;
result++; //삭제된 개수
//System.out.println(queue);
//System.out.println("궁금한 문서의 현재 위치" + answerIndex);
//System.out.println("삭제 된 개수 " + result);
}
else {
num = queue.poll();
queue.offer(num);
if(answerIndex == 0)
answerIndex = queue.size() - 1;
else
answerIndex--;
//System.out.println("가장 큰 중요도는 " + Top);
//System.out.println(queue);
}
}
else if(answerImportance == Top) { //구해야 하는 중요도가 가장 큰 중요도일 때
//System.out.println("넘어옴");
if( Top != queue.peek()) {
num = queue.poll();
queue.offer(num);
--answerIndex;
//System.out.println("작은 애들은 뒤로 보내기");
}
else if(Top == queue.peek()) {
if(answerIndex != 0) {
queue.remove();
result++;
--answerIndex;
//System.out.println("같은 중요도지만 원하는 문서가 아니니까 삭제\n현재 위치" + answerIndex);
}
else {
queue.remove();
result++;
sb.append(result).append('\n');
//System.out.println("최종 삭제 된 순서 " + result);
break;
}
}
}
}
}
System.out.println(sb);
}
}
계속된 오류로 순서를 확인하려고 System.out.println을 많이 사용하였다.
확인용으로 넣은 것 뿐. 실제 코드에는 BufferedWriter나 StringBuilder가 더 효율적임.
같은 언어로 문제를 해결한 사람들은 80ms 정도의 시간복잡도를 가짐.
내 코드는 143ms로 거의 2배가 걸림.
시간복잡도를 줄일 코드를 생각해보자.
반응형
'알고리즘 > 큐' 카테고리의 다른 글
[백준] 1158 : 요세푸스 문제 (0) | 2023.03.26 |
---|