[백준] 10815번: 숫자 카드

2018. 7. 29. 23:57알고리즘

 

10815번: 숫자 카드

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이가 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다. 두 숫자 카드에 같은 수가 적혀있는 경우는 없다. 셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 가지고 있는 숫자 카드인지 아닌지를 구해야 할 M개의 정수가 주어지며, 이

www.acmicpc.net

 

 

이 문제는 이분 탐색 문제에 속합니다.

간단한 이분 탐색의 경우 STL에 속한 binary_search로 해결이 되지만 조금 복잡해질 경우 실제로 구현해야 합니다.

 

이 문제는 간단한 이분 탐색의 문제이기 때문에 STL을 사용해도 되지만 저는 일반적인 이분 탐색 방법을 구현해서 코드를 작성해보았습니다.

 

일반적인 이분 탐색의 방법은 굉장히 간단합니다.

 

이분 탐색은 정렬된 객체들을 이용해야지만 탐색할 수 있는 방법 중 하나인데요.

먼저 left, right 인덱스를 잡고,

left 가 right보다 커지면 종료되는 while 문 안에서 mid를 left와 right를 활용해서 잡아줍니다.

 

이 mid 값이 원하는 값일 때, 종료하면 됩니다.

원하는 값이 아니라면 크기를 비교하여 mid 왼쪽 구간, mid 오른쪽 구간 중 원하는 구간을 선택합니다.

이 선택 방법은 left와 right 값을 mid를 활용해서 바꾸어주는 방법으로 충분합니다.

 

 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N, M;
vector<int> card;
vector<int> num;

void input() {
  cin >> N;
  card.resize(N);
  for (int i = 0; i < N; i++) {
    cin >> card[i];
  }
  sort(card.begin(), card.end());

  cin >> M;
  num.resize(M);
  for (int i = 0; i < M; i++) {
    cin >> num[i];
  }
}

int checkCard(int num) {
  int left = 0;
  int right = N - 1;

  while (left <= right) {
    int mid = (left + right) / 2;

    if (num == card[mid]) {
      return 1;
    }
    else if (num < card[mid]) {
      right = mid - 1;
    }
    else {
      left = mid + 1;
    }
  }
  
  return 0;
}

void printAnswer() {
  for (int i = 0; i < M; i++) {
    cout << checkCard(num[i]) << ' ';
  }
}

int main() {

  ios::sync_with_stdio(false);
  input();
  printAnswer();

  return 0;
}

'알고리즘' 카테고리의 다른 글

[백준] 1932번: 정수 삼각형  (0) 2018.08.01
[백준] 10816번: 숫자 카드 2  (0) 2018.07.30
[백준] 1783번: 병든 나이트  (0) 2018.06.06
[백준] 10610번: 30  (0) 2018.06.03
[백준] 1744번: 수 묶기  (0) 2018.06.03