문제
숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 가지고 있는지 아닌지를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다. 두 숫자 카드에 같은 수가 적혀있는 경우는 없다.
셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 가지고 있는 숫자 카드인지 아닌지를 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다
출력
첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 가지고 있으면 1을, 아니면 0을 공백으로 구분해 출력한다.
문제 이해
문제만 보면 매우 간단해보이지만 시간 초과를 고려해야 하는 문제이다.
두번째로 입력받은 배열의 숫자가 첫번째로 입력받은 배열에 포함 되어있는지를 탐색해야 한다.
시간 초과가 일어나지 않도록 하기 위해서는 이중 for문을 써서 탐색하기 보단 이진 탐색 기법을 사용하여야 한다.
이진탐색
1) 중간값이 찾아야하는 값보다 작을경우 ==> Tail을 mid+1로 설정
2) 중간값이 찾아야하는 값보다 클 경우 ==> Head를 mid-1로 설정
이런식으로 범위를 좁혀가면서 mid값이 찾아야하는 값과 일치하는 경우를 찾으면 된다.
문제 해결
BinarySearch 함수
public static int BinarySearch(int num){ //이진탐색을 위한 함수
int Tail = 0;
int Head = N-1;
while(Tail<=Head){
int Mid = (Tail+Head)/2;
int MiddleValue=arr[Mid];
if(MiddleValue<num){
Tail=Mid+1;
}
else if(MiddleValue>num){
Head=Mid-1;
}
else{
return 1;
}
}
return 0;
}
<전체 코드>
import java.io.*;
import java.nio.Buffer;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Problem10815 {
static int N;
static int M;
static int[] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
arr = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=0; i<N; i++){
arr[i]=Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
M = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
for(int i= 0; i<M; i++){
int num = Integer.parseInt(st.nextToken());
bw.write(BinarySearch(num)+" ");
}
bw.flush();
}
public static int BinarySearch(int num){ //이진탐색을 위한 함수
int Tail = 0;
int Head = N-1;
while(Tail<=Head){
int Mid = (Tail+Head)/2;
int MiddleValue=arr[Mid];
if(MiddleValue<num){
Tail=Mid+1;
}
else if(MiddleValue>num){
Head=Mid-1;
}
else{
return 1;
}
}
return 0;
}
}