
* 배양액들의 조합을 구해서 배치한다.
* 큐를 [초록색 배양액, 빨간색 배양액] 으로 두 개를 사용하는데
depth와 좌표 정보를 넣었다.
depth는 처음에 문제를 잘 못 이해해서 예시를 보고 추가했다.
G | 1 or 2 | R |
이렇게 되어있을 때만 가운데 좌표에 꽃이 필 수 있다.
동시에 도달했을 때의 정보를 넣어줘야 하는데 그 정보를 depth로 기록했다.
*depth를 기록했다면 이 정보를 빠르게 찾아내야 하는데, 이 정보는 dp[][] 배열에 기록해서
빨간색 배양액이 다음에 갈 곳에 이미 초록색 배양액이 있다. -> dp[nx][ny] 가 depth + 1 이면 초록색 배양액이 방금 전에 도달한 곳이다라는 정보를 찾아낼 수 있다. -> 꽃을 틔운다.
*50*50 인데 조합까지 해서 그런지 시간이 꽤 걸린다. 최적화는 나중에..
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | #include <iostream> #include <vector> #include <algorithm> #include <queue> #include <cstring> using namespace std; int n, m, g, r, ans = -1; int map[51][51]; //0은 호수, 1은 배양액을 뿌릴 수 있는 땅, 2 뿌릴 수 없는 땅 //3은 초록색 배양액 4는 빨간색 배양액 5는 꽃으로 정의한다. vector< int > seq; //배양액은 모두 뿌려야 한다. typedef pair< int , int > pp; typedef pair< int , pp> ipp; vector<pp> enable; bool chk[11], visited[51][51]; int dx[4] = {-1,1,0,0}, dy[4] = {0,0,-1,1}; void print() { cout << '\n' ; for ( int i = 0; i < n; i++) { for ( int j = 0; j < m; j++) { if (map[i][j] == 0) cout << "x " ; else cout << map[i][j] << ' ' ; } cout << '\n' ; } cout << '\n' ; } int bfs() { queue<ipp> green, red; int dp[51][51] = {{0}}; memset (visited, 0, sizeof (visited)); for (auto i : enable) { if (map[i.first][i.second] ==3) { green.push(ipp(0,i)); } if (map[i.first][i.second]==4) red.push(ipp(0,i)); } int ret = 0; while (!green.empty() && !red.empty()) { //두 배양액이 만나면 꽃을 틔운다. int size = green.size(); bool flag = false ; //더 이상 나아갈 곳이 없으면 반복문 중단 //그린 먼저 while (size--) { int x = green.front().second.first; int y = green.front().second.second; int depth = green.front().first; green.pop(); if (map[x][y] == 5) continue ; for ( int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx < 0 || nx>= n || ny < 0 || ny>= m || !map[nx][ny] || map[nx][ny] == 5) continue ; if (map[nx][ny] == map[x][y]) continue ; if (map[nx][ny] == 1 || map[nx][ny] == 2) { //해당 배양액으로 바꾼다. map[nx][ny] = map[x][y]; green.push(ipp(depth+1, pp(nx, ny))); dp[nx][ny] = depth+1; } } } size =red.size(); while (size--) { int x = red.front().second.first; int y = red.front().second.second; int depth = red.front().first; red.pop(); if (map[x][y] == 5) continue ; for ( int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx < 0 || nx>= n || ny < 0 || ny>= m || !map[nx][ny] || map[nx][ny] == 5) continue ; if (map[nx][ny] == map[x][y]) continue ; if (map[nx][ny] == 7 - map[x][y]) { if (dp[nx][ny] == depth+1) { map[nx][ny] = 5; ret++; } } if (map[nx][ny] == 1 || map[nx][ny] == 2) { //해당 배양액으로 바꾼다. map[nx][ny] = map[x][y]; red.push(ipp(depth+1,pp(nx, ny))); } } } } return ret; } void dfs( int idx, int cntg, int cntr) { if (cntg == 0 && cntr == 0) { int c_map[51][51]; memcpy (c_map, map, sizeof (map)); int res = bfs(); ans = ans > res ? ans : res; memcpy (map, c_map, sizeof (map)); return ; } for ( int i = idx; i < enable.size(); i++) { if (!chk[i]) { chk[i] = true ; if (cntg-1 >=0){ map[enable[i].first][enable[i].second] = 3; dfs(i+1,cntg-1, cntr); } if (cntr -1 >= 0) { map[enable[i].first][enable[i].second] = 4; dfs(i+1,cntg, cntr-1); } map[enable[i].first][enable[i].second] = 2; chk[i] = false ; } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> m >> g >> r; for ( int i = 0; i < n; i++) { for ( int j = 0; j < m; j++ ) { cin >> map[i][j]; if (map[i][j] == 2) { enable.push_back(pp(i, j)); } } } //input vector< int > requid; for ( int i = 0; i < g; i++) requid.push_back(3); for ( int i = 0; i < r; i++) requid.push_back(4); dfs(0, g, r); //뿌릴 수 있는 땅에 배양액을 배치한다. cout << ans << '\n' ; return 0; } |
'BOJ > C++' 카테고리의 다른 글
[BOJ] 2636. 치즈 (0) | 2020.03.29 |
---|---|
[BOJ] 18808. 스티커 붙이기 (0) | 2020.03.25 |
[BOJ] 10799. 쇠막대기 (C) (0) | 2020.03.24 |
[BOJ] 1158. 요세푸스 문제 (C) (0) | 2020.03.24 |
[BOJ] 2151. 거울설치 + TC (0) | 2020.03.18 |