완전탐색이란?

  • 완전탐색은 Brute-force Search라고 부르며 알고리즘 문제를 해결할 때 기본적으로 처음 접할 수 있는 방법입니다.
  • 한 상황을 생각해 봅시다. 1000개까지 담길 수 있는 배열에서 두개의 가장 큰 수를 찾아 두 수의 합을 출력해보는 문제가 있다고 한다면, 이 두 수를 어떻게 찾을 수 있을까요?
  • 쉽게 생각해서 우리는 for문을 활용해 각 배열의 원소들을 더해보고 가장 큰 값을 구하는 방법을 생각해 볼 수 있습니다.
  • 즉 쉽게 말하면 모든 경우의 수를 다 탐색해보며 찾아보는 방식이고 그렇기 때문에 시간복잡도는 최대로 O(n^2) 의 시간이 소요됩니다.
  • #include <iostream>
    #include <algorithm>
    #include <climits>
    using namespace std;
    int Number;
    int ret = INT_MIN;
    int main()
    {
      int array[1000];
      cin >> Number; // Array의 크기를 입력받습니다.
      for(int i=0;i<Number;i++) // Number의 크기만큼 순회하며 Array의 요소를 채워넣습니다.
        cin >> array[i];
      //여기서 array담긴 숫자들 중 가장 큰 값을 가지는 숫자 2개를 더한 값을 호출해야하는 경우를 생각해봅시다.
      for(int i=0;i<Number;i++)
          for(int j=0;j<Number;j++)
          if (i!=j) // Array의 두 index가 다를 때, 즉 같은숫자의 경우는 제외합니다.
            ret = max(ret, array[i] + array[j]); //return값을 max함수를 통해 더 큰값으로 갱신합니다.
      cout << ret;
      return (0);
    }
  • 위 코드를 살펴보면 Array의 담겨있는 최대 1000개까지 담길 수 있는 배열에서 2개의 큰 수를 찾아 결과를 반환하는 것을 확인할 수 있습니다.
  • 모든 가능한 경우를 다 돌아보기 때문에 Number크기(Array의 크기)의 제곱만큼의 시간이 소요될 수 있습니다.
  • 정답을 찾아내는 방법 중 가장 확실한 방법이지만 그만큼 시간이 많이 소요되기 때문에 알고리즘문제의 제한시간 을 확인해서 사용해야 합니다.
  • c++기준으로 1억번의 시간복잡도를 가질 경우 제한시간이 1초 소요되는 것으로 생각하여 문제를 해결합시다.
  • 완전탐색 알고리즘을 활용한 문제는 다음 게시글에서 확인할 수 있습니다.

https://programmers.co.kr/learn/courses/30/lessons/42584

 

코딩테스트 연습 - 주식가격

초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요. 제한사항 prices의 각 가격은 1 이상 10,00

programmers.co.kr

문제를 처음 확인할 때 생각해볼 수 있는 가장 쉬운 방법으로는 O(n^2) 시간 복잡도를 가지고 있는 완전 탐색이다.

 

그러나 문제를 읽어보면 다음 인덱스 시점의 시간에서 가격이 떨어지느냐 안 떨어지느냐에 따라 return값이 결정된다는 것을 확인할 수 있다.

 

한 가지 주의해야 할 점은 다음 인덱스가 이전 인덱스보다 작다는 것을 알기 전 시간은 이미 1초가 흘렀다고 생각하는 것이고

 

전부 다 돌아보는 것이 아닌 두 번째 for문부터는 바로 앞 인덱스부터 탐색을 시작하면 해결할 수 있다.

 

문제의 분류로는 스택과 큐 카테고리에 존재하지만 오히려 스택과 큐를 활용하여 해결방법을 생각해보더라도 오히려 코드가 더 길어질 것 같으며 큰 차이가 없을 것 같아 다음과 같이 완전 탐색과 같은 방법으로 해결하였다.

 

3 언어의 코드 방식도 전부 동일하며 문제 예시에 대한 이해를 빠르게 한다면 빠른 시간 내에 해결할 수 있을 것 같다.

 

C++

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> prices) 
{
    vector<int> answer;
    for(int i=0;i<prices.size();i++)
    {
        int cnt=0;
        for(int j=i+1;j<prices.size();j++)
        {
            cnt++;
            if (prices[i] > prices[j])
                break;
        }
        answer.push_back(cnt);
    }
    return answer;
}

Java

class Solution 
{
    public int[] solution(int[] prices) 
    {
        int[] answer = new int[prices.length];
        for(int i=0;i<prices.length;i++)
        {
            for (int j=i + 1;j<prices.length;j++)
            {
                answer[i]++;
                if (prices[i]>prices[j])
                    break;
            }
        }
        return answer;
    }
}

Python3

def solution(prices):
    answer = [0] * len(prices)
    # prices 크기만큼 빈 리스트를 할당.
    for i in range(0,len(prices)):
        for j in range(i + 1, len(prices)):
            answer[i] += 1
            if prices[i]>prices[j]:
                break;
    return answer

 

도형의 종류별로 회전과 대칭의 index를 확인해보며 넣었을 경우 얻는 값을 최대로 경신해주기만 하면 풀리는 막일 문제였다. 꼼꼼하게 체크할게 거의 없었고 가능하면 정리해서 코드를 짜야 하지만 역량테스트를 치른다는 가정하에 가장 빠르게 해결하기 위하여 너저분하게 코드가 짜였다.

https://github.com/ukjinlee66/BOJ/blob/master/14500.cpp

 

ukjinlee66/BOJ

baekjoon. Contribute to ukjinlee66/BOJ development by creating an account on GitHub.

github.com

https://www.acmicpc.net/problem/14500

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다. 정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다. 아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누

www.acmicpc.net

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int map[501][501];
int n,m;
int res;
bool check(int x, int y)
{
    if (x<1 || y<1 || x>|| y>m) return false;
    return true;
}
void one(int x, int y)
{
    if (check(x + 1, y + 1&& check(x + 1, y) && check(x, y + 1))
        res = max(res, map[x + 1][y + 1+ map[x + 1][y] + map[x][y + 1+ map[x][y]);
}
void two(int x, int y)
{
    if (check(x + 1, y) && check(x + 2, y) && check(x + 3, y))
        res = max(res, map[x][y] + map[x + 1][y] + map[x + 2][y] + map[x + 3][y]);
    //회전
    if (check(x, y + 1&& check(x, y + 2&& check(x, y + 3))
        res = max(res, map[x][y] + map[x][y + 1+ map[x][y + 2+ map[x][y + 3]);
}
void three(int x, int y)
{
    if (check(x + 1, y) && check(x + 2, y) && check(x + 2, y + 1))
        res = max(res,map[x][y] + map[x + 1][y] + map[x + 2][y] + map[x + 2][y + 1]);
    //회전 3가지.
    if (check(x, y + 1&& check(x, y + 2&& check(x - 1, y + 2))
        res = max(res, map[x][y] + map[x][y + 1+ map[x][y + 2+ map[x - 1][y + 2]);
    if (check(x, y + 1&& check(x + 1, y + 1&& check(x + 2, y + 1))
        res = max(res, map[x][y] + map[x][y + 1+ map[x + 1][y + 1+ map[x + 2][y + 1]);
    if (check(x + 1, y) && check(x, y + 1&& check(x, y + 2))
        res = max(res, map[x][y] + map[x + 1][y] + map[x][y + 1+ map[x][y + 2]);
    //반전1 +회전 3가지
    if (check(x, y + 1&& check(x - 1, y + 1&& check(x - 2, y + 1))
        res = max(res, map[x][y] + map[x][y + 1+ map[x - 1][y + 1+ map[x - 2][y + 1]);
    if (check(x, y + 1&& check(x, y + 2&& check(x + 1, y + 2))
        res = max(res, map[x][y] + map[x][y + 1+ map[x][y + 2+ map[x + 1][y + 2]);
    if (check(x, y + 1&& check(x + 1, y) && check(x + 2, y))
        res = max(res, map[x][y] + map[x][y + 1+ map[x + 1][y] + map[x + 2][y]);
    if (check(x + 1, y) && check(x + 1, y + 1&& check(x + 1, y + 2))
        res = max(res, map[x][y] + map[x + 1][y] + map[x + 1][y + 1+ map[x + 1][y + 2]);
}
void four(int x, int y)
{
    if (check(x + 1, y) && check(x + 1, y + 1&& check(x + 2, y + 1))
        res = max(res, map[x][y] + map[x + 1][y] + map[x + 1][y + 1+ map[x + 2][y + 1]);
    if (check(x, y + 1&& check(x - 1, y + 1&& check(x - 1, y + 2))
        res = max(res, map[x][y] + map[x][y + 1+ map[x - 1][y + 1+ map[x - 1][y + 2]);
    if (check(x + 1, y) && check(x, y + 1&& check(x - 1, y + 1))
        res = max(res, map[x][y] + map[x + 1][y] + map[x][y + 1+ map[x - 1][y + 1]);
    if (check(x, y + 1&& check(x + 1, y + 1&& check(x + 1, y + 2))
        res = max(res, map[x][y] + map[x][y + 1+ map[x + 1][y + 1+ map[x + 1][y + 2]);
}
void five(int x, int y)
{
    if (check(x, y + 1&& check(x, y + 2&& check(x - 1, y + 1))
        res = max(res, map[x][y] + map[x][y + 1+ map[x][y + 2+ map[x - 1][y + 1]);
    if (check(x, y + 1&& check(x + 1, y + 1&& check(x - 1, y + 1))
        res = max(res, map[x][y] + map[x][y + 1+ map[x + 1][y + 1+ map[x - 1][y + 1]);
    if (check(x, y + 1&& check(x, y + 2&& check(x + 1, y + 1))
        res = max(res, map[x][y] + map[x][y + 1+ map[x][y + 2+ map[x + 1][y + 1]);
    if (check(x + 1, y) && check(x + 2, y) && check(x + 1, y + 1))
        res = max(res, map[x][y] + map[x + 1][y] + map[x + 2][y] + map[x + 1][y + 1]);
}
void sol(int x,int y,int number) //도형의 번호를받음. (1~5)
{
    switch (number)
    {
    case 1:
        one(x, y);
        break;
    case 2:
        two(x, y);
        break;
    case 3:
        three(x, y);
        break;
    case 4:
        four(x, y);
        break;
    case 5:
        five(x, y);
        break;
    }
    return;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> map[i][j];
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            for (int k = 1; k <= 5; k++)
            {
                sol(i, j, k);
            }
        }
    }
    cout << res;
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

'Problem Solving > 삼성 역량테스트' 카테고리의 다른 글

BOJ-17406 배열돌리기 4  (0) 2019.11.10
BOJ-17837 새로운 게임2  (0) 2019.11.06
BOJ-12100 2048(Easy)  (0) 2019.11.06
BOJ-17144 미세먼지 안녕  (0) 2019.11.06
BOJ-17780 새로운 게임  (0) 2019.11.05

+ Recent posts