티스토리 뷰
https://www.acmicpc.net/problem/12100
2048 게임을 최대 5번 이동해서 만들 수 있는 가장 큰 블럭의 값을 구하는 문제이다. 일단 상하좌우 4가지 경우에 대하여 4^5=1024개의 경우를 모두 만든다. 그리고 실제로 블럭들을 이동시켜 본다. 해당 방향에 대하여 먼저 블럭들 사이에 빈칸이 없게 밀고나서 인접한 블럭의 값들이 같으면 합쳐준다. 이 때 합친 후에 블럭 사이에 빈칸이 다시 생기므로 한번 더 밀어야 한다.
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 | #include <cstdio> #include <vector> #include <algorithm> using namespace std; int n,board[20][20],ans; vector<int> path; int solve() { int b[20][20]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) b[i][j]=board[i][j]; for(int k=0;k<5;k++) { if(path[k]==1) // 상 { for(int j=0;j<n;j++) // 위로 밀기 { int idx=0; for(int i=0;i<n;i++) { if(b[i][j]!=0) { if(i==idx) idx++; else b[idx][j]=b[i][j],b[i][j]=0,idx++; } } } for(int j=0;j<n;j++) for(int i=0;i<n-1;i++) // 블럭 합치기 if(b[i][j]==b[i+1][j]) b[i][j]*=2,b[i+1][j]=0; for(int j=0;j<n;j++) // 다시 위로 밀기 { int idx=0; for(int i=0;i<n;i++) { if(b[i][j]!=0) { if(i==idx) idx++; else b[idx][j]=b[i][j],b[i][j]=0,idx++; } } } } else if(path[k]==2) // 하 { for(int j=0;j<n;j++) { int idx=n-1; for(int i=n-1;i>=0;i--) { if(b[i][j]!=0) { if(i==idx) idx--; else b[idx][j]=b[i][j],b[i][j]=0,idx--; } } } for(int j=0;j<n;j++) for(int i=n-1;i>0;i--) if(b[i][j]==b[i-1][j]) b[i][j]*=2,b[i-1][j]=0; for(int j=0;j<n;j++) { int idx=n-1; for(int i=n-1;i>=0;i--) { if(b[i][j]!=0) { if(i==idx) idx--; else b[idx][j]=b[i][j],b[i][j]=0,idx--; } } } } else if(path[k]==3) // 좌 { for(int i=0;i<n;i++) { int idx=0; for(int j=0;j<n;j++) { if(b[i][j]!=0) { if(j==idx) idx++; else b[i][idx]=b[i][j],b[i][j]=0,idx++; } } } for(int i=0;i<n;i++) for(int j=0;j<n-1;j++) if(b[i][j]==b[i][j+1]) b[i][j]*=2,b[i][j+1]=0; for(int i=0;i<n;i++) { int idx=0; for(int j=0;j<n;j++) { if(b[i][j]!=0) { if(j==idx) idx++; else b[i][idx]=b[i][j],b[i][j]=0,idx++; } } } } else if(path[k]==4) // 우 { for(int i=0;i<n;i++) { int idx=n-1; for(int j=n-1;j>=0;j--) { if(b[i][j]!=0) { if(j==idx) idx--; else b[i][idx]=b[i][j],b[i][j]=0,idx--; } } } for(int i=0;i<n;i++) for(int j=n-1;j>0;j--) if(b[i][j]==b[i][j-1]) b[i][j]*=2,b[i][j-1]=0; for(int i=0;i<n;i++) { int idx=n-1; for(int j=n-1;j>=0;j--) { if(b[i][j]!=0) { if(j==idx) idx--; else b[i][idx]=b[i][j],b[i][j]=0,idx--; } } } } } int ret=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) ret=max(ret,b[i][j]); return ret; } void go(int cnt) // 1:상 2:하 3:좌 4:우 { if(cnt==5) { ans=max(ans,solve()); return; } for(int i=1;i<=4;i++) { path.push_back(i); go(cnt+1); path.pop_back(); } } int main() { scanf("%d",&n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&board[i][j]); go(0); printf("%d\n",ans); return 0; } | cs |
'Algorithm > BOJ' 카테고리의 다른 글
14499 주사위 굴리기 (0) | 2018.04.06 |
---|---|
13458 시험 감독 (0) | 2018.04.06 |
13567 로봇 (0) | 2018.04.02 |
12026 BOJ 거리 (0) | 2018.03.30 |
5525 IOIOI (0) | 2018.03.14 |