티스토리 뷰
#문제
https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5V1SYKAaUDFAWu
#풀이
모의 SW 역량 테스트 문제들중 하나 입니다.
역시 삼성 문제스럽게 나왔습니다.
저는 이 문제를 완탐으로 풀었습니다.
SW 역량 테스트관련 알고리즘들을 푸는지라... 계속 완탐 문제만 푸는것 같습니다......
문제 해결 방식은 다음과 같습니다.
각 막에서 약품을 안뿌리고 넘어갈 것인가?
아니면 뿌리는데 A를 뿌릴것인가, B를 뿌릴것인가
총 3가지 길로 나누어 모든 경우의 수를 돌렸습니다.
이 때, 중요한 점이 있습니다.
완전 탐색을 하기 위해서는 그전의 film을 복사 하여야 합니다.
(이유는 그 전 알고리즘 풀이에도 많이 있습니다 -> 치킨배달 : http://jongnan.tistory.com/34)
복사할때 만약 film 전체를 복사한다고 해봅시다.
배열의 최대 크기가 13×20 이고, 재귀 호출을 돌린다면 최대 13×4번(복사를 4번 하기 때문에), 다 돌렸을 때 K를 만족하는지에 대해서도 확인을 해야하므로 엄청난 시간이 들게 됩니다.
따라서 전체 배열을 복사하는 것이 아닌 해당 막만 복사합니다.
그렇다면 시간이 확 줄겠죠? :)
검사를 통과 하는 것에 대해서는 이차원 배열을 돌면서 확인하는 것이므로 잘 하실꺼라 믿습니다!
처음에 저는 깊이를 1로 시작해서... 2번째 부터 약품을 뿌릴건지 안뿌릴건지 확인을 하는 불상사를...
그것 때문에 반례도 다 찾아봤는데 다 맞았다는... 실수를 조심합니다. :)
#코드
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 | #include <iostream> #define INF 987654321 #define W_MAX 20 #define M_MAX 13 using namespace std; int film[M_MAX][W_MAX]; int D,W,K; int ans; void init(){ for(int i = 0; i < M_MAX; i++){ for(int j = 0; j < W_MAX; j++){ film[i][j] = 0; } } } void copyfloor(int a[W_MAX], int b[W_MAX]){ for(int i = 0; i < W; i++){ a[i] = b[i]; } } void spreadMedicine(int d, int kind){ for(int i = 0; i < W; i++){ film[d][i] = kind; } } //성능 시험을 통과하는지 확인 //만약 통과를 한다면 그때의 뿌린 횟수를 저장 void checkFilm(int cnt){ for(int i = 0; i < W; i++){ int hap = 1; for(int j = 0; j < D-1; j++){ if(hap >= K){ break; } if(film[j][i] == film[j+1][i]){ hap += 1; }else{ hap = 1; } } if(hap < K){ return; } } if(ans > cnt){ ans = cnt; } } void dfs(int d, int cnt){ if(cnt > ans){ return; } if(d >= D){ checkFilm(cnt); return; } //각 층에서 약품을 뿌리거나, 안뿌리거나 둘중 하나 //뿌릴 경우에는 A를 뿌리느냐, B를 뿌리느냐! //(1) 안뿌릴 경우 dfs(d+1, cnt); //약품을 뿌릴 경우에는 전 상황을 저장하여 모든 경우의 수를 확인 //(2) A를 뿌릴 경우 int temp[W]; copyfloor(temp, film[d]); spreadMedicine(d, 0); dfs(d+1, cnt+1); copyfloor(film[d], temp); //(3) B를 뿌릴 경우 copyfloor(temp, film[d]); spreadMedicine(d, 1); dfs(d+1, cnt+1); copyfloor(film[d], temp); } int main(){ int T; cin >> T; for(int t = 1; t <= T; t++){ init(); cin >> D >> W >> K; //film 받기 for(int i = 0; i < D; i++){ for(int j = 0; j < W; j++){ cin >> film[i][j]; } } ans = INF; dfs(0,0); cout << "#" << t <<" " <<ans << endl; } return 0; } | cs |
'알고리즘 문제 풀이 > SW Expert' 카테고리의 다른 글
[SW Expert 5650] 핀볼 게임 (0) | 2018.10.16 |
---|---|
[SW Expert 5653] 줄기세포배양 (1) | 2018.10.15 |
[SW Expert 5656] 벽돌 깨기 (1) | 2018.10.14 |
[SW Expert 5658] 보물상자 비밀번호 (0) | 2018.10.13 |
[SW Expert 5644] 무선 충전 (6) | 2018.10.12 |