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

블로그 메뉴

  • 홈
  • 분류 전체보기 (217) N
    • BOJ (170) N
      • 스택 (14)
      • 큐 (5)
      • 덱 (4)
      • 그래프 (30)
      • 배열 (8)
      • 재귀 (12)
      • 브루트 포스 (2)
      • 그리디 알고리즘 (7)
      • 다이내믹 프로그래밍 (13) N
      • 백트래킹 (24)
      • 기하학 (4)
      • 트리 (4)
      • 구현 (14)
      • 수학 (3)
      • 맵 (1)
      • 다익스트라 (2)
      • 누적합 (4) N
    • 자료구조 (14)
      • 스택 (3)
      • 큐 (5)
      • 덱 (2)
      • 그래프 (1)
      • 트리 (1)
      • 힙 (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

10816번: 숫자 카드 2

2022. 2. 4. 23:24

10816번: 숫자 카드 2(BOJ C/C++)

사용 언어: C

문제

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 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개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 몇 개 가지고 있는지를 공백으로 구분해 출력한다.

 

첫 번째 풀이

이분 탐색으로 푸는 것은 알았지만, 통상적인 이분 탐색으로는 중복되는 부분까지는 잡아낼 수 없기 때문에 일단 카운팅 정렬로 풀었다. 카운팅 정렬의 풀이는 메모리가 추가적으로 필요해 공간 복잡도가 높은 대신 시간 복잡도가 O(N)으로 유동적이다(빠를 수도, 느릴 수도).

#include <stdio.h>

int arr[20000001];

int main(void)
{
	int N,M,num;
	scanf("%d",&N);
	for(int i=0;i<N;i++)
	{
		scanf("%d",&num);
		arr[num+10000000]++;
	}
	scanf("%d",&M);
	int data[M];
	for(int i=0;i<M;i++)
		scanf("%d",&data[i]);
	for(int i=0;i<M;i++)
		printf("%d ",arr[data[i]+10000000]);

    return 0;
}

 

두 번째 풀이

이분 탐색으로도 푸는 방법을 알고 싶어서, 다른 분들의 풀이를 참고해봤는데, 이해가 잘 안가지만 이분 탐색의 상한과 하한 값을 빼면 값이 나온다 한다. 원래 이분 탐색은 시간 복잡도가 O(logN)이지만, 여기서는 이분 탐색을 두번 실행하므로 2*O(logN)로 볼 수 있을 것 같다. 백준에서는 첫 풀이가 더 빨랐지만, N이 많이 커진다면 이 풀이가 첫 풀이보다 빨라질 것 같다.

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

int compare(const void *a, const void *b)    // 오름차순 비교 함수 구현
{
    int num1 = *(int *)a;
    int num2 = *(int *)b;

    if(num1 < num2)
        return -1;
    
    if(num1 > num2)
        return 1;
    
    return 0;
}

int lower_binary_search(int arr[], int target, int size) //하한
{
	int mid, start, end;
    start = 0, end = size - 1;
 
    while (end > start)
	{
        mid = (start + end) / 2;
        if (arr[mid] >= target)
            end = mid;
        else start = mid + 1;
    }
    return end;
}

int upper_binary_search(int arr[], int target, int size) //상한
{
	int mid, start, end;
    start = 0, end = size - 1;
 
    while (end > start)
	{
        mid = (start + end) / 2;
        if (arr[mid] > target)
            end = mid;
        else start = mid + 1;
    }
    return end;
}

int main(void)
{
    int lower, upper;
	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],res[M];
	for(int i=0;i<M;i++)
	{
		scanf("%d",&data[i]);
		res[i]=0;
	}
	qsort(arr, sizeof(arr)/sizeof(int), sizeof(int),compare);
	for (int i = 0; i < M; i++) 
	{
        lower = lower_binary_search(arr, data[i], N);
        upper = upper_binary_search(arr, data[i], N);
        if (upper == N - 1 && arr[N - 1] == data[i])
            upper++;
        res[i] = upper - lower;
    }
	for (int i=0; i<M; i++)
        printf("%d ",res[i]);

    return 0;
}

 

세 번째 풀이

또 다른 분의 풀이를 보다가 트리로 이 문제를 푸신 본을 봐서 그냥 이렇게 풀 수도 있겠구나~ 생각해서 링크 정도만 올려본다. https://sedangdang.tistory.com/24

 

느낀 점

하나의 문제에서도 이렇게 다양하게 풀 수 있다는 점에서 코딩의 재미를 다시 한번 느낀다. 아자아자 파이팅!

 

저작자표시 (새창열림)

'BOJ' 카테고리의 다른 글

11650번: 좌표 정렬하기  (1) 2024.09.26
18870번: 좌표 압축  (0) 2024.09.26
1929번: 소수 구하기  (0) 2022.01.27
2480번: 주사위 세개  (0) 2022.01.15
2752번: 세수정렬  (0) 2022.01.12
    'BOJ' 카테고리의 다른 글
    • 11650번: 좌표 정렬하기
    • 18870번: 좌표 압축
    • 1929번: 소수 구하기
    • 2480번: 주사위 세개
    둠치킨
    둠치킨
    코딩 공부를 위한 코딩 블로그 기록 일기

    티스토리툴바