반응형
문제에서 요구한 대로 약품을 투입한다.
이 때, DFS에서 매번 MAP을 copy하는 비용을 낮추기 위해 약간의 테크닉을 사용할 수 있다.
특성 A가 0, B가 1이므로, MAP[1]에는 0을, MAP[2]에는 1을 저장해둔다.
int MAP[3][MAX][MAX];
int list[MAX];
void input()
{
scanf("%d %d %d", &D, &W, &K);
for (int r = 1; r <= D; r++)
for (int c = 1; c <= W; c++)
scanf("%d", &MAP[0][r][c]);
}
int main(void)
{
/* MAP[2]에는 모두 B약품 1 저장 */
for (int r = 1; r <= MAX - 1; r++)
for (int c = 1; c <= MAX - 1; c++) MAP[2][r][c] = 1;
...
}
이렇게 해두고, list에는 약품을 투입하지 않을지, A를 투입할지, B를 투입할지를 DFS로 만들면 된다.
따라서 성능검사를 통과하는지 check하는 함수는 아래처럼 만들 수 있다.
list가 모두 0이라면, list[r]은 모두 0이기 때문에 MAP[0] → 입력값을 그대로 보고 성능검사를 한다.
list[r]이 1이라면 MAP[1], 즉 A 약품만 보게 되고, list[r]이 2 라면 B 약품만 보게 된다.
/* 1 = A, 2 = B */
int list[MAX];
int check(int col)
{
int cnt, tmp;
cnt = 1;
tmp = MAP[list[1]][1][col];
for (int r = 2; r <= D; r++)
{
if (cnt == K) return 1;
if (tmp == MAP[list[r]][r][col]) cnt++;
else
{
tmp = MAP[list[r]][r][col];
cnt = 1;
}
}
if (cnt == K) return 1;
return 0;
}
int allCheck()
{
for (int c = 1; c <= W; c++)
if (check(c) == 0) return 0;
return 1;
}
DFS는 약품을 투입하지 않는 경우, A를 투입하는 경우, B를 투입하는 경우로 만들면 된다.
약품을 투입하지 않는 경우는 cnt를 증가시킬 필요가 없다.
또한 이미 답이 나온 경우보다 cnt가 커진다면 더 이상 DFS를 진행할 필요가 없다.
int MINANS = 0x7fff0000;
void DFS(int L, int cnt)
{
if (MINANS <= cnt) return;
if (L > D)
{
if (allCheck())
{
if (cnt < MINANS) MINANS = cnt;
}
return;
}
list[L] = 0;
DFS(L + 1, cnt);
list[L] = 1;
DFS(L + 1, cnt + 1);
list[L] = 2;
DFS(L + 1, cnt + 1);
}
최종 코드는 아래와 같다.
#include <stdio.h>
#define MAX (25 + 5)
int T, D, W, K;
int MAP[3][MAX][MAX];
void input()
{
scanf("%d %d %d", &D, &W, &K);
for (int r = 1; r <= D; r++)
for (int c = 1; c <= W; c++)
scanf("%d", &MAP[0][r][c]);
}
/* 1 = A, 2 = B */
int list[MAX];
int check(int col)
{
int cnt, tmp;
cnt = 1;
tmp = MAP[list[1]][1][col];
for (int r = 2; r <= D; r++)
{
if (cnt == K) return 1;
if (tmp == MAP[list[r]][r][col]) cnt++;
else
{
tmp = MAP[list[r]][r][col];
cnt = 1;
}
}
if (cnt == K) return 1;
return 0;
}
int allCheck()
{
for (int c = 1; c <= W; c++)
if (check(c) == 0) return 0;
return 1;
}
int MINANS = 0x7fff0000;
void DFS(int L, int cnt)
{
if (MINANS <= cnt) return;
if (L > D)
{
if (allCheck())
{
if (cnt < MINANS) MINANS = cnt;
}
return;
}
list[L] = 0;
DFS(L + 1, cnt);
list[L] = 1;
DFS(L + 1, cnt + 1);
list[L] = 2;
DFS(L + 1, cnt + 1);
}
int main(void)
{
/* MAP[2]에는 모두 B약품 1 저장 */
for (int r = 1; r <= MAX - 1; r++)
for (int c = 1; c <= MAX - 1; c++) MAP[2][r][c] = 1;
scanf("%d", &T);
for (int tc = 1; tc <= T; tc++)
{
input();
MINANS = 0x7fff0000;
DFS(1, 0);
printf("#%d %d\n", tc, MINANS);
}
return 0;
}
반응형
'알고리즘 > [ADV] 삼성 SW Expert Academy A형' 카테고리의 다른 글
SWEA 1953 : 탈주범 검거 (모의 SW 역량테스트) (0) | 2021.05.20 |
---|---|
SWEA 2105 : 디저트 카페 (모의 SW 역량테스트) (0) | 2021.05.17 |
SWEA 2117 : 홈 방범 서비스 (모의 SW 역량테스트) (0) | 2021.05.11 |
SWEA 2382 : 미생물 격리 (모의 SW 역량테스트) (1) | 2021.05.09 |
SWEA 2383 : 점심 식사시간 (모의 SW 역량테스트) (0) | 2021.05.07 |
댓글