백준 19637 (좀 IF문 좀 대신 써줘) - Java
이 문제를 처음 풀었을 때에 반복문을 중첩해서 풀었더니 시간초과가 났다.
문제가 되었을 것이라 생각했던 부분은
for (int i = 0; i < M; i++) {
int score = Integer.parseInt(br.readLine());
for (int j = 0; j < N; j++) {
if (score <= titleScore[j]) {
bw.write(title[j] + "\n");
break;
}
}
}
이 부분의 코드인데, 현재 입력받는 점수가 저장되어 있는 구분 전투력의 점수보다 작은지 비교하는 부분이다. (작은 순으로 저장하기 때문에 인덱스 순서대로 비교해도 문제 없을 듯)
헌데 시간초과가 났기 때문에 아마도 반복문을 중첩해서 일어난 문제라고 생각했다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
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));
// 첫 번째 라인 읽기
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
// 칭호 갯수
int N = Integer.parseInt(st.nextToken());
// 캐릭터 갯수
int M = Integer.parseInt(st.nextToken());
// 칭호 (WEAK, NORMAL...)
String[] title = new String[N];
// 칭호에 따른 전투력 점수
int[] titleScore = new int[N];
// 칭호와 전투력 각각 할당
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine(), " ");
String tmpTitle = st.nextToken();
int tmpTitleScore = Integer.parseInt(st.nextToken());
title[i] = tmpTitle;
titleScore[i] = tmpTitleScore;
}
for(int i = 0;i < M;i++){
// 입력 받은 전투력
int currScore = Integer.parseInt(br.readLine());
// 첫번째 인덱스
int low = 0;
// 마지막 인덱스
int high = N - 1;
// 가운데 인덱스
int mid = (low + high) / 2;
// 이분 탐색 -> 절반씩 줄여나가는 방법
while (low <= high){
mid = (low + high) / 2;
// 전투력 중간 값이 현재 입력 받은 전투력보다 작으면
// 첫번째 인덱스를 가운데 인덱스 + 1로 지정
if(titleScore[mid] < currScore){
low = mid + 1;
}
// 전투력 중간 값이 현재 입력 받은 전투력보다 크거나 같으면
// 마지막 인덱스를 가운데 인덱스 - 1로 지정
else{
high = mid - 1;
}
}
// low가 high가 되는 시점에서 끝이 나기 때문에
// title[low]가 찾던 칭호 (low가 찾던 인덱스 위치)
bw.write(title[low]+"\n");
}
bw.flush();
bw.close();
br.close();
}
}
잘 읽었습니다. 좋은 정보 감사드립니다.