둠치킨
코딩하는 둠치킨
둠치킨

블로그 메뉴

  • 홈
  • 분류 전체보기 (231)
    • 프로그래머스 (3)
      • 해시 (1)
      • 다익스트라 (1)
      • 크루스칼 (1)
    • BOJ (180)
      • 스택 (14)
      • 큐 (5)
      • 덱 (4)
      • 그래프 (32)
      • 배열 (8)
      • 재귀 (12)
      • 브루트 포스 (2)
      • 그리디 알고리즘 (7)
      • 다이내믹 프로그래밍 (14)
      • 백트래킹 (24)
      • 기하학 (4)
      • 트리 (4)
      • 구현 (14)
      • 수학 (3)
      • 맵 (1)
      • 다익스트라 (2)
      • 누적합 (5)
      • 유니온 파인드 (1)
      • 분할 정복 (2)
      • 벨만-포드 (1)
      • 이분 탐색 (5)
    • 자료구조 (15)
      • 스택 (3)
      • 큐 (5)
      • 덱 (2)
      • 그래프 (1)
      • 트리 (2)
      • 힙 (1)
      • 정렬 (1)
    • C++ (11)
      • 모두의코드 (2)
      • Effective C++ (3)
      • C++ STL (6)
    • 컴파일러 (1)
    • OS (17)
    • 컴퓨터 구조 (2)
    • Unreal Engine 5 (2)

공지사항

전체 방문자
오늘
어제

인기 글

최근 글

태그

  • BFS
  • boj
  • Bruteforce
  • C
  • C++
  • C++ STL
  • Cache Memory
  • deadlock
  • DFS
  • Effective C++
  • java
  • Mutex
  • next_permutation
  • os
  • Process
  • rotate
  • semaphore
  • spin lock
  • STL
  • STL C++
hELLO · Designed By 정상우.
둠치킨

코딩하는 둠치킨

BOJ/이분 탐색

1920번: 수 찾기

2022. 1. 13. 23:29

1920번: 수 찾기(BOJ C/C++)

사용 언어: C

문제

N개의 정수 A[1], A[2], …, A[N]이 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들이 A안에 존재하는지 알아내면 된다. 모든 정수의 범위는 -231 보다 크거나 같고 231보다 작다.

출력

M개의 줄에 답을 출력한다. 존재하면 1을, 존재하지 않으면 0을 출력한다.

 

풀이

문제를 한번 쓱 읽어보면 이중 for문으로 간단하게 풀 수 있을거라고 착각할 수 있지만 이미 백준 문제를 많이 접해본 이상 이렇게 간단히 풀릴 수가 없다. 이중 for문으로 쓰면 시간복잡도는 O(n^2)까지 올라갈 수 있다. 그래서 이분 탐색(이진 탐색)으로 바로 풀 생각을 할 수 있다. 아니면 해시를 사용해서 풀 수도 있겠지만... 아직 해시를 공부한 적이 없기 때문에 언젠가 공부해서 해시 구현 글도 올려보겠다..! 

 

어쨌든 이분 탐색은 시간복잡도가 O(logn)이므로 이중 for문 보다 확실히 빠르고 알아야 할 것이 정렬된 리스트 혹은 배열에서 사용하는 것이므로 입력 받은 배열을 정렬해줘야 한다. 그럼 여기서도 시간복잡도를 따져야하는데 퀵소트가 pivot에 따라 시간복잡도가 최대 O(n^2)일 수 있지만 평균적으로 O(nlogn)이므로 퀵소트를 사용한다. 퀵소트는 그냥 stdlib.h에 있는 qsort 함수를 사용했다.

 

여담으로 밑에 compare(const void *a,~) 에서 const를 붙이는 이유는 이미 고정된 배열 값을 인자로 넘기는데 함수 안에서 이 값을 고의로 혹은 실수로 변경하는 것은 안되서 애초에 컴파일러가 금지하므로 const를 붙여야 오류가 안 뜬다.

#include <stdio.h>
#include <stdlib.h>

int compare(const void *a, const void *b)    // 오름차순 비교 함수 구현
{
    int num1 = *(int *)a;    // void 포인터를 int 포인터로 변환한 뒤 역참조하여 값을 가져옴
    int num2 = *(int *)b;    // void 포인터를 int 포인터로 변환한 뒤 역참조하여 값을 가져옴

    if(num1 < num2) //a가 b보다 작을 때는 -1 반환
        return -1;
    
    if(num1 > num2) //a가 b보다 클 때는 1 반환
        return 1;
    
    return 0; //a와 b가 같을 때는 0 반환
}

int binary_search(int num, int arr[], int low, int high)
{
	int mid;
	while (low <= high)
	{
		mid = (low + high) / 2;
		//탐색 성공
		if (num == arr[mid])
			return 1;
		
		// 탐색 범위 재조정 low ~ mid-1
		else if (num < arr[mid])
			high = mid - 1;
		
		// 탐색 범위 재조정 mid+1 ~ high	
		else if (num > arr[mid])
			low = mid + 1;
	}
	return 0;
}

int main(void)
{
    int low,high,mid;
	int N,M;
	scanf("%d",&N);
	int arr[N];
	for(int i=0;i<N;i++)
		scanf("%d",&arr[i]);
	scanf("%d",&M);
	int data[M];
	for(int i=0;i<M;i++)
		scanf("%d",&data[i]);
	low=0;
	high=N;
	qsort(arr, sizeof(arr)/sizeof(int), sizeof(int),compare);
	for(int i=0;i<M;i++)
		printf("%d\n",binary_search(data[i], arr, low, high));
	
    return 0;
}
저작자표시 (새창열림)

'BOJ > 이분 탐색' 카테고리의 다른 글

1300번: K번째 수  (0) 2025.09.12
1654번: 랜선 자르기  (0) 2024.09.27
2110번: 공유기 설치  (0) 2024.09.27
10816번: 숫자 카드 2  (0) 2022.02.04
    'BOJ/이분 탐색' 카테고리의 다른 글
    • 1300번: K번째 수
    • 1654번: 랜선 자르기
    • 2110번: 공유기 설치
    • 10816번: 숫자 카드 2
    둠치킨
    둠치킨
    코딩 공부를 위한 코딩 블로그 기록 일기

    티스토리툴바