5656번 벽돌 깨기
해결방법
모든 경우에 대해 탐색하여 구현 하는
완전탐색 + 시뮬레이션
문제이다
⭐️ 솔루션 ⭐️
구슬은 총 4개를 발사할 수 있고, 가로의 최대 길이는 12 이므로 탐색에는
O(12^4)
의 시간이 걸린다완전탐색은
DFS
로 구현하였고, 구슬이 파괴되는 과정은BFS
를 통해 구현하였다중력에 의해 벽돌을 내리는 로직을 설계하였는데, 테케 50개 중 49개만 맞아서 다른 코드를 참고해 로직을 변경하였다
소스코드
문제 해결 시간 : 2h
메모리 : 12652 KB
시간 : 1681 ms
#include <iostream>
#include <math.h>
#include <vector>
#include <queue>
#define INF 987654321
using namespace std;
struct node {
int x,y,range;
node() { }
node(int _x,int _y,int _range) : x(_x),y(_y),range(_range) { }
};
int testcase;
int n,r,c,ans;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
vector<vector<int>> map;
void printMap(vector<vector<int>> v){
cout << "\n";
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
cout << v[i][j] << " ";
}
cout << "\n";
}
cout << "\n";
}
vector<vector<int>> bombBlock(vector<vector<int>> v,int col){
// 구슬이 명중하는 노드 찾기
int row = -1;
for(int i=r-1; i>=0; i--){
if(v[i][col] == 0){
row = i;
break;
}
}
if(row == r-1) return v;
else if(row == -1) row = 0;
else row += 1;
queue<node> q;
q.push(node(row,col,v[row][col]));
v[row][col] = 0;
while(!q.empty()){
int x = q.front().x;
int y = q.front().y;
int range = q.front().range;
q.pop();
for(int i=0; i<4; i++){
int nx = x;
int ny = y;
for(int j=1; j<range; j++){
nx += dx[i];
ny += dy[i];
if(nx<0 || ny<0 || nx>=r || ny>=c) continue;
if(v[nx][ny]>=1){
q.push(node(nx,ny,v[nx][ny]));
v[nx][ny] = 0;
}
}
}
}
return v;
}
vector<vector<int>> downBlock(vector<vector<int>> v){
for(int i=r-1; i>=0; i--){
for(int j=0; j<c; j++){
if(v[i][j] != 0){
int row = i;
int col = j;
while(1){
if(v[row+1][col]!=0 || row+1>=r) break;
v[row+1][col] = v[row][col];
v[row][col] = 0;
row++;
}
}
}
}
return v;
}
int getBlock(vector<vector<int>> v){
int res = 0;
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
if(v[i][j] != 0) res++;
}
}
return res;
}
void dfs(vector<vector<int>> v,int cnt){
// n개의 구술을 쐈다면
if(cnt == n){
ans = min(ans,getBlock(v));
return;
}
for(int i=0; i<c; i++){
vector<vector<int>> tmp = bombBlock(v,i);
tmp = downBlock(tmp);
dfs(tmp,cnt+1);
}
}
int main(int argc, const char * argv[]) {
// cin,cout 속도향상
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> testcase;
for(int tc=1; tc<=testcase; tc++){
cin >> n >> c >> r;
map.clear();
map.assign(r+1,vector<int>(c+1,0));
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
cin >> map[i][j];
}
}
ans = INF;
dfs(map,0);
cout << "#" << tc << " " << ans << "\n";
}
return 0;
}
'Algorithm > SWEA 문제풀이' 카테고리의 다른 글
[SWEA] 4408번 자기 방으로 돌아가기 (0) | 2019.03.15 |
---|---|
[SWEA] 4261번 빠른 휴대전화 키패드 (0) | 2019.03.15 |
[SWEA] 5644번 무선 충전 (0) | 2019.03.15 |
[SWEA] 4014번 활주로 건설 (0) | 2019.03.15 |
[SWEA] 4013번 특이한 자석 (0) | 2019.03.15 |