boardcover2 시간초과 ckdhyeon95 boardcover2 문제 시간초과를 해결하고자 질문드립니다. 종만북을 참고하여 block의 상대좌표 구하기 vector unique를 통해 block 중복 제거 block으로 map을 덮을 수 있는지 확인 3.1 덮을 수 없다면 다음칸 확인 3.2 덮을 수 있다면 map을 block으로 덮은 뒤 다음칸 확인, 덮지 않은 채 다음칸 확인 (모두 고려) 휴리스틱을 이용하여 가지치기 위 개념을 바탕으로 접근하여 알고리즘을 구현하였습니다. 하지만 시간초과가 납니다. 세부적인 구현에서 차이가 나서 시간초과가 나는건지, 혹은 제가 고려하지 못한 부분이 있는지 알고싶습니다. #include <iostream> #include <cstring> #include <vector> #include <utility> #include <algorithm> using namespace std; char mapArr[10][10]; char block[10][10]; int inputH, inputW, inputR, inputC; vector<vector<pair<int, int> > > coordinate(4); //block의 상대좌표 vector int resultVal = -1; int bNum = 0; //block size // 배열 돌리기 함수 void rotateArr() { char tempArr[10][10]; for (int i = 0; i < inputR; ++i) { for (int j = 0; j < inputC; ++j) { tempArr[j][i] = block[inputR - 1 - i][j]; } } int temp = inputR; inputR = inputC; inputC = inputR; memcpy(block, tempArr, sizeof(block)); } // block의 상대좌표 구하는 함수 void getCoordinate() { for (int i = 0; i < 4; ++i) { int firstR = -1; int firstC = -1; for (int j = 0; j < inputR * inputC; ++j) { int nowR = j / inputC; int nowC = j % inputC; if (block[nowR][nowC] != '#') continue; if (firstR == -1 && firstC == -1) { firstR = nowR; firstC = nowC; } coordinate[i].push_back(make_pair(nowR - firstR, nowC - firstC)); } rotateArr(); } } // block을 놓을 수 있는지 확인하는 함수 bool isPossible(int nowR, int nowC, int type) { bool check = true; for (int i = 0; i < coordinate[type].size(); ++i) { int nextR = nowR + coordinate[type][i].first; int nextC = nowC + coordinate[type][i].second; if (nextR < 0 || nextR >= inputH || nextC < 0 || nextC >= inputW) { check = false; break; } if (mapArr[nextR][nextC] != '.') { check = false; break; } } return check; } //mapArr에 block을 넣는 함수 void writeMap(int nowR, int nowC, int type) { for (int i = 0; i < coordinate[type].size(); ++i) { int nextR = nowR + coordinate[type][i].first; int nextC = nowC + coordinate[type][i].second; mapArr[nextR][nextC] = 'a'; } } void solve(int pos, int cnt) { int nowR = -1; int nowC = -1; int space = 0; for (int i = pos; i < inputH * inputW; ++i) { int tempR = i / inputW; int tempC = i % inputW; if (mapArr[tempR][tempC] == '.') { space += 1; if (nowR == -1 && nowC == -1) { nowR = tempR; nowC = tempC; } } } int heuristic = space / bNum; if (cnt + heuristic <= resultVal) return; // 가지치기 if (nowR == -1 && nowC == -1) { resultVal = max(resultVal, cnt); return; } int ret = 0; char backup[10][10]; //mapArr 백업을 위한 배열 //현재 좌표(nowR, nowC)를 시작점으로 삼는 경우 for (int type = 0; type < coordinate.size(); ++type) { if (!isPossible(nowR, nowC, type)) continue; memcpy(backup, mapArr, sizeof(backup)); //백업한뒤 writeMap(nowR, nowC, type); //mapArr에 block넣고 solve(pos + 1, cnt + 1); //재귀호출 memcpy(mapArr, backup, sizeof(mapArr)); //mapArr 복원 } //현재 좌표(nowR, nowC)를 건너뛰는 경우 solve(pos + 1, cnt); } int main() { int testCase; cin >> testCase; while (testCase-- > 0) { //초기화 bNum = 0; resultVal = -1; memset(mapArr, 0, sizeof(mapArr)); memset(block, 0, sizeof(block)); coordinate = vector<vector<pair<int, int> > >(4); cin >> inputH >> inputW >> inputR >> inputC; for (int i = 0; i < inputH; ++i) { for (int j = 0; j < inputW; ++j) cin >> mapArr[i][j]; } for (int i = 0; i < inputR; ++i) { for (int j = 0; j < inputC; ++j) { cin >> block[i][j]; if (block[i][j] == '#') bNum += 1; } } //우선 block의 상대좌표 구한 뒤 getCoordinate(); // 중복제거 후 sort(coordinate.begin(), coordinate.end()); coordinate.erase(unique(coordinate.begin(), coordinate.end()), coordinate.end()); // solve함수 호출 solve(0, 0); cout << resultVal << '\n'; } return 0; } 4년 전
0개의 댓글이 있습니다. 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.
ckdhyeon95
boardcover2 문제 시간초과를 해결하고자 질문드립니다.
종만북을 참고하여
block으로 map을 덮을 수 있는지 확인
3.1 덮을 수 없다면 다음칸 확인
3.2 덮을 수 있다면 map을 block으로 덮은 뒤 다음칸 확인, 덮지 않은 채 다음칸 확인 (모두 고려)
휴리스틱을 이용하여 가지치기
위 개념을 바탕으로 접근하여 알고리즘을 구현하였습니다.
하지만 시간초과가 납니다.
세부적인 구현에서 차이가 나서 시간초과가 나는건지,
혹은 제가 고려하지 못한 부분이 있는지 알고싶습니다.
4년 전