Brute Force

· β˜• 3 min read · πŸ‘€... views

Brute Force (λ¬΄μ‹ν•˜κ²Œ ν’€κΈ°)

1. κ°œμš”

  • μ‚¬λžŒλ“€μ΄ κ°€μž₯ 많이 ν•˜λŠ” μ‹€μˆ˜λŠ” μ‰¬μš΄ 문제λ₯Ό μ–΄λ ΅κ²Œ ν‘ΈλŠ” 것
  • 문제λ₯Ό λ§ˆμ£Όν•˜κ³  λ‚˜λ©΄ κ°€μž₯ λ¨Όμ € λ¬΄μ‹ν•˜κ²Œ ν’€ 수 μžˆμ„κΉŒ λΌλŠ” μ§ˆλ¬Έμ„ μŠ€μŠ€λ‘œμ—κ²Œ ν•˜μž
  • 말 κ·ΈλŒ€λ‘œ μ»΄ν“¨ν„°μ˜ λΉ λ₯Έ 계산 λŠ₯λ ₯을 μ΄μš©ν•΄ κ°€λŠ₯ν•œ 경우의 수λ₯Ό 일일이 λ‚˜μ—΄ν•˜λ©΄μ„œ 닡을 μ°ΎλŠ” 방법
  • 이런 방법을 ν”νžˆ μ™„μ „ 탐색 이라고 λΆ€λ₯΄κ³ , μ™œ ꡳ이 μ–ΈκΈ‰ν• κΉŒ μ‹Άμ§€λ§Œ, μ»΄ν“¨ν„°μ˜ μž₯점은 κ²°κ΅­ 속도가 λΉ λ₯΄λ‹€λŠ” 것이기에 μž₯점을 잘 ν™œμš©ν•˜λŠ” 것이기도 ν•˜λ‹€.

2. μž¬κ·€ 호좜과 μ™„μ „ 탐색

2-1. μž¬κ·€ 호좜(ν•¨μˆ˜)

  • μž¬κ·€ 호좜(ν•¨μˆ˜) λž€ μžμ‹ μ΄ μˆ˜ν–‰ν•  μž‘μ—…μ„ μœ μ‚¬ν•œ ν˜•νƒœμ˜ μ—¬λŸ¬ 쑰각으둜 μͺΌκ°  λ’€ κ·Έ 쀑 ν•œ 쑰각을 μˆ˜ν–‰ν•˜κ³ , λ‚˜λ¨Έμ§€λ₯Ό 자기 μžμ‹ μ„ ν˜ΈμΆœν•΄ μ‹€ν–‰ν•˜λŠ” ν•¨μˆ˜λ₯Ό 가리킴

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    // 1λΆ€ν„° nκΉŒμ§€μ˜ 합을 κ΅¬ν•˜λŠ” 반볡문과 μž¬κ·€ν•¨μˆ˜
    int sum(int n) {
      int ret = 0;
      for(int i = 1; i <= n; i++) {
        ret += i;
      }
      return ret;
    }
      
      
    int recursiveSum(int n) {
      if(n == 1) {
        return 1;
      }
      return n + recursiveSum(n-1);
    }
    
  • μž¬κ·€ν•¨μˆ˜μ˜ 경우 if 문에 μ£Όλͺ©μ„ ν•˜λ©΄, 이 쑰건문이 μ—†μœΌλ©΄ ν•¨μˆ˜κ°€ μ œλŒ€λ‘œ λ™μž‘μ„ ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. n=1 이면 쑰각이 ν•˜λ‚˜ λΏμ΄λ‹ˆ, ν•œ 개λ₯Ό λΉΌκ³  λ‚˜λ©΄ 더 이상 μ²˜λ¦¬ν•  μž‘μ—…μ΄ μ—†κΈ° λ•Œλ¬Έ.

  • λͺ¨λ“  μž¬κ·€ ν•¨μˆ˜λŠ” 이와 같이 더이상 μͺΌκ°œμ§€μ§€ μ•ŠλŠ” μ΅œμ†Œν•œμ˜ μž‘μ—…μ— 도달햇을 λ•Œ 닡을 곧μž₯ λ°˜ν™˜ν•˜λŠ” 쑰건문을 포함해야 ν•˜λŠ”λ°. 이λ₯Ό κΈ°μ € 사둀 (base case) 라고 ν•œλ‹€.

  • κΈ°μ € 사둀λ₯Ό 선택할 λ•ŒλŠ” μ‘΄μž¬ν•˜λŠ” λͺ¨λ“  μž…λ ₯이 항상 κΈ°μ € μ‚¬λ‘€μ˜ 닡을 μ΄μš©ν•΄ 계산될 수 μžˆλ„λ‘ 해야함. λ§Œμ•½μ— n 이 1인 경우λ₯Ό ν™•μΈν•˜λŠ” 게 μ•„λ‹ˆλΌ 2라면 3을 λ°˜ν™˜ν•œλ‹€κ³  ν•˜λ©΄ μž…λ ₯이 2 이상일 λ•ŒλŠ” λ¬Έμ œκ°€ μ—†μ§€λ§Œ, 1이 λ“€μ–΄μ˜€λ©΄ λ¬Έμ œκ°€ 생김

2-2. 예제) 보글 κ²Œμž„

  • 5x5 크기의 μ•ŒνŒŒλ²³ 격자λ₯Ό 가지고 ν•˜λŠ” κ²Œμž„μœΌλ‘œ μƒν•˜μ’Œμš°/λŒ€κ°μ„ μœΌλ‘œ μΈμ ‘ν•œ μΉΈλ“€μ˜ κΈ€μžλ₯Ό 이어 단어λ₯Ό μ°Ύμ•„λ‚΄λŠ” κ²Œμž„

  • hasWord(x, y, word) = 보글 κ²Œμž„νŒμ˜ (y,x)μ—μ„œ μ‹œμž‘ν•˜λŠ” 단어 word 의 μ‘΄μž¬μ—¬λΆ€λ₯Ό λ°˜ν™˜ν•œλ‹€.

    U R L P M
    X P R E T
    G I A E T
    X T N Z Y
    X O Q R S
  • 문제의 λΆ„ν• 
    1. κ°€μž₯ μžμ—°μŠ€λŸ¬μš΄ 방법은 각 κΈ€μžλ₯Ό ν•˜λ‚˜μ˜ 쑰각으둜 λ§Œλ“œλŠ” 것
    2. ν•¨μˆ˜ ν˜ΈμΆœμ‹œμ— λ‹¨μ–΄μ˜ μ‹œμž‘ μœ„μΉ˜λ₯Ό μ •ν•΄ μ£ΌκΈ° λ•Œλ¬Έμ— 첫 κΈ€μžκ°€ λ‹€λ₯΄λ©΄ λ°”λ‘œ false
    3. κ·Έ μ΄ν›„μ˜ word[1..] 의 μ‹œμž‘ μœ„μΉ˜λŠ” 첫 κΈ€μžμ˜ μœ„μΉ˜μ—μ„œ μΈμ ‘ν•œ 8μΉΈ 쀑 ν•˜λ‚˜ μ΄λ―€λ‘œ, μ—¬λŸ 경우λ₯Ό λͺ¨λ‘ μ‹œλ„ν•˜μ—¬ 닡을 찾으면 됨
  • κΈ°μ € μ‚¬λ‘€μ˜ 선택
    1. μœ„μΉ˜ (y,x) 에 μžˆλŠ” κΈ€μžκ°€ μ›ν•˜λŠ” λ‹¨μ–΄μ˜ 첫 κΈ€μžκ°€ μ•„λ‹Œ 경우 항상 μ‹€νŒ¨
    2. (1λ²ˆμ— ν•΄λ‹Ήν•˜μ§€ μ•Šμ„ 경우) μ›ν•˜λŠ” 단어가 ν•œ κΈ€μžμΈ 경우 항상 성곡
    3. (팁) μž…λ ₯이 잘λͺ»λ˜κ±°λ‚˜, λ²”μœ„μ—μ„œ λ²—μ–΄λ‚œ κ²½μš°λ„ κΈ°μ € μ‚¬λ‘€λ‘œ μ„ νƒν•΄μ„œ λ²—μ–΄λ‚˜κ²Œ ν•˜λŠ” 방법이 있음
  • κ΅¬ν˜„
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    private int[8] dx = {-1, -1, -1, 1, 1, 1, 0, 0}
    private int[8] dy = {-1, 0, 1, -1, 0, 1, -1, 1}
      
    public boolean hasWord(int y, int x, String word) {
      //κΈ°μ € 사둀 1 : μ‹œμž‘ μœ„μΉ˜κ°€ λ²”μœ„ 밖이면 무쑰건 μ‹€νŒ¨ 
      if(!inRange(y, x)) {
        return false;
      }
      //κΈ°μ € 사둀 2 : 첫 κΈ€μžκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠμœΌλ©΄ μ‹€νŒ¨
      if(board[y][x] != word.charAt(0)) {
        return false;
      }
      //κΈ°μ € 사둀 3 : 단어 길이가 1이면 성곡
      if(word.length() == 1) {
        return true;
      }
      //μΈμ ‘ν•œ μ—¬λŸ 칸을 검사
      for(int direction = 0; direction < 8; direction++) {
        int nextY = y + dy[direction];
        int nextX = x + dx[direction];
        // λ‹€μŒ 칸이 λ²”μœ„ μ•ˆμ— μžˆλŠ”μ§€, 첫 κΈ€μžλŠ” μΌμΉ˜ν•˜λŠ”μ§€ 확인할 ν•„μš” μ—†μŒ
        if(hasWord(nextY, nextX, word.substring(1))) {
          return true;
        }
      }
      return false;
    }
    
    μ‹œκ°„ λ³΅μž‘λ„ 뢄석
    • μ‹œκ°„ λ³΅μž‘λ„λ₯Ό κ³„μ‚°ν•˜λŠ” 것은 비ꡐ적 λ‹¨μˆœν•˜λ‹€. κ°€λŠ₯ν•œ λ‹΅ 후보듀을 λͺ¨λ‘ λ§Œλ“€μ–΄ 보기 떄문에 μ‹œκ°„ λ³΅μž‘λ„λ₯Ό κ³„μ‚°ν•˜κΈ° μœ„ν•΄μ„œλŠ” κ°€λŠ₯ν•œ ν›„λ³΄μ˜ 수λ₯Ό μ „λΆ€ μ„Έμ–΄ 보기만 ν•˜λ©΄ 됨
    • ν˜„μž¬ κ²€μ‚¬ν•˜λŠ” ν›„λ³΄μ˜ μˆ˜λŠ” μ΅œλŒ€ 8^N-1 = O(8^N)이 되고, 이것이 μ‹œκ°„ λ³΅μž‘λ„κ°€ 됨
    • ν›„λ³΄μ˜ μˆ˜λŠ” λ‹¨μ–΄μ˜ 길이에 따라 μ§€μˆ˜μ μœΌλ‘œ μ¦κ°€ν•˜κΈ° λ•Œλ¬Έμ— λ‹¨μ–΄μ˜ 길이가 짧은 κ²½μš°μ—λ§Œ ν•˜λ„λ‘ν•˜κ³ , λ‹¨μ–΄μ˜ 길이가 μ‘°κΈˆμ΄λΌλ„ κΈΈμ–΄μ§ˆ 경우 동적 κ³„νšλ²• 등을 μ‚¬μš©ν•΄μ•Ό 함

3. κ΄€λ ¨ 문제

  • λͺ¨λ“  μˆœμ—΄(permutation) λ§Œλ“€κΈ°
  • λͺ¨λ“  μ‘°ν•©(combination) λ§Œλ“€κΈ°
  • 2^n 가지 경우의 수 λ§Œλ“€κΈ°
Share on

snack
WRITTEN BY
snack
Web Programmer


What's on this Page