문제
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
풀이
* 조합을 사용해서 백트래킹을 하며 모든 경우를 다 해본다.
* 첫 행과 마지막 행은 흰색 / 빨간색으로 고정된다.
2행부터 n-1 행까지의 조합을 구한다.
* 조합을 구할 때 파란색이 반드시 포함되어야 한다.
* W = 1
B = 2
R = 3
으로 치환을 했다.
색을 칠 할 때 이전의 행에 칠해진 색과 숫자가 같거나, 더 큰 숫자만 칠할 수 있다.
예를 들어, 흰 -> 파 (O) / 파 -> 흰(X)
파 -> 빨 (O) / 빨 -> 파(X)
* 이 특징을 이용해서 모든 경우를 전부 구하지 않고도 정답을 구할 수 있다.
* chk[] => 이 배열에는 각 행마다 칠해질 색의 수가 지정된다.
* n-1 행까지 칠해질 색이 정해졌다면 calc() 에서 정해진 색으로 바꾸기 위해 몇 개의 칸을 바꿔야 하는지 계산하여 반환한다.
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 113 114 115 116 117 118 119 120 | #include <iostream> #include <vector> #include <cstring> #define INF 987654321 using namespace std; //SWEA 4613. 러시아 국기 같은 깃발 int color[51][51]; int n, m; int ans = INF; int chk[51]; int calc() { int ret = INF; for ( int i = 1; i < n - 1; i++) { if (chk[i] == 2) { ret = 0; break ; } //이 색으로 바꿔야 하낟. } if (!ret) { for ( int i = 1; i < n - 1; i++) { int flag = chk[i]; for ( int j = 0; j < m; j++) { if (color[i][j] != flag) { ret++; } } } } return ret; } void dfs( int x, int c) { if (x == n - 1) { int res = calc(); ans = min(ans, res); return ; } if (!chk[x]) { int prev = chk[x - 1]; for ( int j = prev; j <= 3; j++) { chk[x] = j; dfs(x + 1, j); chk[x] = 0; } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int t; cin >> t; for ( int tc = 1; tc <= t; ++tc) { cin >> n >> m; memset (color, 0, sizeof (color)); memset (chk, 0, sizeof (chk)); for ( int i = 0; i < n; ++i) { for ( int j = 0; j < m; ++j) { char c; cin >> c; if (c == 'W' ) color[i][j] = 1; else if (c == 'B' ) color[i][j] = 2; else if (c == 'R' ) color[i][j] = 3; } } //조합으로 구하기 ans = INF; int res = 0; for ( int j = 0; j < m; ++j) { if (color[0][j] != 1) { res++; color[0][j] = 1; } if (color[n - 1][j] != 3) { res++; color[n - 1][j] = 3; } } //1행부터 n-2행까지는 흰 -> 파 -> 빨 순서대로 와야 한다. //각각 몇 개의 행을 차지하는 지는 조합으로 구한다. dfs(1, 1); cout << "#" << tc << " " << res + ans << '\n' ; } return 0; } |
'SWEA > D5' 카테고리의 다른 글
[SWEA] 1249. 보급로 (0) | 2020.05.18 |
---|---|
[SWEA] 1824. 혁진이의 프로그램 검증 (0) | 2020.05.04 |
[SWEA 7393][D4][JAVA] 대규의 팬덤활동 (0) | 2019.05.14 |
[SWEA 4411][D5][JAVA] 덕환이의 카드 뽑기 (0) | 2019.05.08 |