백트래킹 18

[백준 14888] 연산자 끼워넣기 [Python]

풀이 N개의 수에 대해 N - 1개의 수식을 적용해 모든 경우를 생각해도 크기가 작아 충분하다. 하지만, 연산자 우선순위에 관계없이 왼쪽부터 오른쪽으로 연산을 하면 되기 때문에 중복해 계산하는 부분이 있다. 이 부분에 대한 값을 stack에 저장해 재사용 하는 방법으로 풀이했다. 0 ~ N-1 번의 index에 대한 탐색이 끝났다면, 최댓값과 최솟값을 갱신해주고, 그렇지 않은 경우에는 아직 사용할 수 있는 연산자에 대해 계산을 해주자. 소스코드 소스코드 보기 출처 14888번: 연산자 끼워넣기 첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의..

[백준 1799] 비숍 [C]

풀이 최악의 경우 모든 체스판의 정보가 1로만 이루어질 때, 시간초과가 발생하기 때문에, 효율적으로 풀이해야 한다. 모든 경우를 고려할 때 시간초과가 발생하는 이유 중 하나는 비숍이 규칙적으로 놓일 수 있는 공간에 대해 생각하지 않기 때문이다. 다음처럼 비숍을 놓는 경우를 생각해보자 즉, 흰색과 회색에 놓일 수 있는 비숍으로 구분해서 탐색한다면 규칙적으로 놓일 수 있는 공간대로 탐색할 수 있다. 입력받은 체스판의 정보에 대해 만약 놓을 수 없는 공간이라면 다음 공간으로 넘어가면 된다. 소스코드 #include #include bool board[11][11], l[19], r[19]; int N, result[2]; void bishop(int row, int col, int cnt, int color)..

[백준 1987] 알파벳 [C]

풀이 입력된 대문자 알파벳의 아스키코드 값을 이용해, 한 번이라도 방문한 적 없는 경우에만 탐색해 최대의 칸 수를 구하면 된다. 소스코드 #include #include char arr[20][20]; bool visited[26]; int R, C, result; int dx[4] = {-1, 1}, dy[4] = {0, 0, -1, 1}; void BT(int x, int y, int cnt){ cnt > result && (result = cnt); for (int i = 0; i = 0 && ny >= 0 && nx < R && ny < C){ int idx = arr[nx][ny] - 65; if ..

[백준 2023] 신기한 소수 [C]

풀이 8자리수의 소수를 확인하기 위해 1e8만큼의 공간을 할당하면 메모리 제한에 막힌다. 심지어 조건에 맞는 모든 소수의 개수가 100개도 안된다. 때문에, 다음과 같은 규칙을 찾아 문제를 해결했다. N의 자릿수는 2, 3, 5, 7 이어야 한다. 2를 제외한 모든 짝수는 소수가 아니기 때문에 홀수만 탐색해야 한다. 소스코드 #include #include int prime(int num){ int sq = sqrt(num); for (int i = 2; i

[백준 2239] 스도쿠 [C]

풀이 스도쿠를 완성시키고, 81자리의 수가 제일 작은 경우를 출력하면 되는 문제이다. Backtracking방식으로 스도쿠에 넣어줄 수 있는 작은 수 부터 탐색하면서, 만약 81번째 자리에 도달했다면 가장 작은 81자리의 수를 완성시킨 것이기 때문에 출력을 해주고 중단을 해줘야한다. 소스코드 #include int arr[9][9], print = 1; int check(int x, int y, int val){ for (int i = 0; i < 9; i++) if (arr[x][i] == val || arr[i][y] == val) return 0; x = (x/3)*3; y = (y/3)*3; for (int i = x; i < x+3; i++) for (int j = y; j < y+3; j++)..

[백준 15666] N과 M (12) [C]

풀이 "백준 15664, N과 M (10)"에서 기존에 i번째 요소를 사용했는지를 확인하기 위해 사용한 check를 빼면 해결할 수 있다. 소스코드 #include #include int N, M, arr[8], visited[8]; int compare(const void *a, const void *b){ return *(int*)a - *(int*)b; } void BT(int depth, int start){ for (int i = start, temp = 0; i < N; i++) if (temp != arr[i]){ temp = visited[depth] = arr[i]; if (depth + 1 == M){ for (int idx = 0; idx < M; idx++) printf("%d ",..

[백준 15665] N과 M (11) [C]

풀이 "백준 15663, N과 M (9)"에서 기존에 i번째 요소를 사용했는지를 확인하기 위해 사용한 check를 빼면 해결할 수 있다. 소스코드 #include #include int N, M, arr[7], visited[7]; int compare(const void *a, const void *b){ return *(int*)a - *(int*)b; } void BT(int depth){ for (int i = 0, temp = 0; i < N; i++) if (temp != arr[i]){ temp = visited[depth] = arr[i]; if (depth + 1 == M){ for (int idx = 0; idx < M; idx++) printf("%d ", visited[idx]); ..

[백준 15656] N과 M (7) [C]

풀이 "백준 15651, N과 M (3)"와 비슷하다. 1부터 N까지가 아닌 입력받은 수에 대해 모든 조합 가능한 수를 출력하면 된다. 소스코드 #include #include int N, M, visited[7], arr[7]; int compare(const void *a, const void *b){ return *(int*)a - *(int*)b; } void BT(int depth){ for (int i = 0; i < N; i++){ visited[depth] = arr[i]; if(depth + 1 == M){ for (int idx = 0; idx < M; idx++) printf("%d ", visited[idx]); putchar(10); }else BT(depth + 1); } } i..

[백준 15655] N과 M (6) [C]

풀이 "백준 15664, N과 M (10)"에서 사용한 코드로 해결이 된다. 소스코드 #include #include #include bool check[8]; int N, M, arr[8], visited[8]; int compare(const void *a, const void *b){ return *(int*)a - *(int*)b; } void BT(int depth, int start){ for (int i = start, temp = 0; i < N; i++) if (!check[i] && temp != arr[i]){ temp = visited[depth] = arr[i]; check[i] = true; if (depth + 1 == M){ for (int idx = 0; idx < M; i..