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 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Main { public static int[][] maps; public static int n,max, count; public static void main(String[] args) throws FileNotFoundException { //FileInputStream fi = new FileInputStream("C:\\Users\\SeonMi\\Desktop\\JavaTools\\Tools\\workspace\\Solution\\src\\data.txt"); Scanner sc = new Scanner(System.in); //Scanner sc = new Scanner(fi); n = sc.nextInt(); maps = new int[n+1][n+1]; max =0; for(int i=1;i<n+1;i++){ for(int j=1;j<n+1;j++){ maps[i][j]=sc.nextInt(); if(maps[i][j]>max) max=maps[i][j]; // 입력받은 수 중 가장 큰 값 저장 } } count = 0; move(0, maps); // 재귀함수 이용 System.out.println(max); } /* -----------------------------------------------------------------*/ /* * 1번째 Maps에서 L,R,U,D 를 해준다. L의 경우, 회전 후 row, col 이 1~n번째 인덱스가 있음을 가정하고, 순회1) col 1~n까지 순회하는 동안 내부에서는 순회 2)row i = 1~n-1 까지 순회하고 순회 3(그 안에서 j=i+1~n 까지 순회하여 0이 아닌 같은 숫자가 있으면 더해주고(L방향으로 하나는 sum 다른 하나는 0으로 교환), 다른 숫자라면 더할 수 없으므로 다음 row로 넘어가 같은 수 탐색한다. 각 라인에 합한 수가 구해졌다면, pullNumber()함수를 통해 숫자 중간에 0의 공백이 있으면 당겨준다. 1번째 L에서 또 move호출, 2번째 L,R,U,D 진행하여 5번째에 break; 해준다. */ /* -----------------------------------------------------------------*/ public static void move(int _count, int[][] _maps){ // 입력받은 맵을 LRUD 다 해줌 int count = _count; if(count<5){ int[][] copiedMaps = new int[n+1][n+1]; for(int a=1;a<5;a++){ // LRUD 해주기 if(a==1){ copiedMaps = copyMaps(_maps); // 배열 복사(값이 아닌 주소를 받아오기 때문에 대입은 금지.) for(int lCol=1;lCol<n+1;lCol++){ // 각 Col 마다 숫자를 더하고 정렬한다. for(int lRow=1;lRow<n;lRow++){ // pivot을 이용해 같은 숫자가 있으면 더해준다. 0 0 1 1 경우, 0 0 2 0 으로 변함. if(copiedMaps[lCol][lRow]!=0){ // 0이 아닌 수를 비교해야 함. for(int point = lRow+1; point<=n;point++){ // row+1 ~ n 까지 같은 수 탐색 if(copiedMaps[lCol][point]!=0){ // 0이 아닌 경우, 같은지 다른지 비교 후 같다면 합해준다. if(copiedMaps[lCol][lRow]==copiedMaps[lCol][point]) copiedMaps = sumNumber(copiedMaps,1,lCol,lRow,point); break; // 숫자의 동등 여부 비교했으므로 다음 row를 탐색. } } } } copiedMaps = pullNumber(copiedMaps, 1, lCol, 0); // 0 0 2 0 을 2 0 0 0 으로 당겨주는 역할. } move(count+1,copiedMaps); } if(a==2){ copiedMaps = copyMaps(_maps); for(int lCol=1;lCol<n+1;lCol++){ for(int lRow=n;lRow>1;lRow--){ if(copiedMaps[lCol][lRow]!=0){ for(int point = lRow-1; point>=1;point--){ if(copiedMaps[lCol][point]!=0){ if(copiedMaps[lCol][lRow]==copiedMaps[lCol][point]) copiedMaps = sumNumber(copiedMaps,2,lCol,lRow,point); break; } } } } copiedMaps = pullNumber(copiedMaps, 2, lCol, 0); } move(count+1,copiedMaps); } if(a==3){ copiedMaps = copyMaps(_maps); for(int lRow=1;lRow<n+1;lRow++){ for(int lCol=1;lCol<n;lCol++){ if(copiedMaps[lCol][lRow]!=0){ for(int point = lCol+1; point<=n;point++){ if(copiedMaps[point][lRow]!=0){ if(copiedMaps[lCol][lRow]==copiedMaps[point][lRow]) copiedMaps =sumNumber(copiedMaps,3,lCol,lRow,point); break; } } } } copiedMaps =pullNumber(copiedMaps, 3, 0, lRow); } move(count+1,copiedMaps); } if(a==4){ copiedMaps = copyMaps(_maps); for(int lRow=1;lRow<n+1;lRow++){ for(int lCol=n;lCol>1;lCol--){ if(copiedMaps[lCol][lRow]!=0){ for(int point = lCol-1; point>=1;point--){ if(copiedMaps[point][lRow]!=0){ if(copiedMaps[lCol][lRow]==copiedMaps[point][lRow]) copiedMaps =sumNumber(copiedMaps,4,lCol,lRow,point); break; } } } } copiedMaps = pullNumber(copiedMaps, 4, 0, lRow); } move(count+1,copiedMaps); } } } } public static int[][] sumNumber(int[][] copiedMaps, int dir, int lCol, int lRow, int point) { if(dir==2 || dir ==1) //L,R 인 경우 좌 우로 더함{ { copiedMaps[lCol][lRow]+=copiedMaps[lCol][point]; copiedMaps[lCol][point]=0; } else // U,D 인 경우 위 아래로 더함 { copiedMaps[lCol][lRow]+=copiedMaps[point][lRow]; copiedMaps[point][lRow]=0; } if(copiedMaps[lCol][lRow]>max) max = copiedMaps[lCol][lRow]; return copiedMaps; } public static int[][] copyMaps(int[][] _maps) { int maps[][] = new int[n+1][n+1]; for(int i=1;i<n+1;i++){ for(int j=1;j<n+1;j++){ maps[i][j]=_maps[i][j]; } } return maps; } public static int[][] pullNumber(int[][] copiedMaps, int dir, int Col, int Row){ switch(dir){ case 1:{ // Left 0 당긴다. for(int point=1;point<n;point++){ // point와 idx를 이용해 point 이후에 0이 있으면 앞으로 당겨준다. if(copiedMaps[Col][point]==0){ for(int idx=point+1;idx<=n;idx++){ if(copiedMaps[Col][idx]!=0){ copiedMaps[Col][point]=copiedMaps[Col][idx]; copiedMaps[Col][idx]=0; break; } } } } break; } case 2:{ // R 0 당김 for(int point=n;point>1;point--){ // point와 idx를 이용해 point 이후에 0이 있으면 뒤로 당겨준다. if(copiedMaps[Col][point]==0){ for(int idx=point-1;idx>=1;idx--){ if(copiedMaps[Col][idx]!=0){ copiedMaps[Col][point]=copiedMaps[Col][idx]; copiedMaps[Col][idx]=0; break; } } } } break; } case 3:{ // UP 0 당김 for(int point=1;point<n;point++){ // point와 idx를 이용해 point 이후에 0이 있으면 앞으로 당겨준다. if(copiedMaps[point][Row]==0){ for(int idx=point+1;idx<=n;idx++){ if(copiedMaps[idx][Row]!=0){ copiedMaps[point][Row]=copiedMaps[idx][Row]; copiedMaps[idx][Row]=0; break; } } } } break; } case 4:{ // D 0 당기기 for(int point=n;point>1;point--){ // point와 idx를 이용해 point 이후에 0이 있으면 뒤로 당겨준다. if(copiedMaps[point][Row]==0){ for(int idx=point-1;idx>=1;idx--){ if(copiedMaps[idx][Row]!=0){ copiedMaps[point][Row]=copiedMaps[idx][Row]; copiedMaps[idx][Row]=0; break; } } } } } break; } return copiedMaps; } } | cs |
풀이시간 ) 3시간 반;;;;
풀이 )
각 방향(L,R,U,D) 기준 각 라인의 수를 비교해 SUM을 구하고 PULL하여 빈 공백(0)이 있으면 당겨주었다.
예를 들어
nxn의 배열이 있다고 가정하고(1~N까지)
특정 COL이 다음과 같이 주어진 경우, L할 경우
1 0 0 1 0 0 2 4 4
2 0 0 0 0 0 2 4 4
(ROW R=1~n-1까지 탐색, 그 내부에서 POINT=ROW+1~n 까지 탐색해서 POINT가 0이 아닌 수이면서, POINT=r이면 더해주고 아니면 다음 ROW로 BREAK)
2 0 0 0 0 0 2 4 4
2 0 0 0 0 0 2 8 0
2 2 8 0 0 0 0 0 0
Left부터 빈공백(0)이 있으면 당겨준다.
다른 풀이)
for(각각의 라인){
빈 공백을 당겨준 후 => 인접 인덱스가 같으면 SUM 해주고 => 다시 빈 공백을 당겨준다.
}
주의할 점
SWITCH CASE 종료시 꼭 BREAK 해줄 것. 아니면 다음 CASE가 실행된다.
'공부 > Algorithm' 카테고리의 다른 글
백준 알고리즘[큐] 3190 - 뱀 (1) | 2017.09.02 |
---|---|
백준 알고리즘[재귀] 13460 - 째로탈출2(다시 풀어보기) (0) | 2017.09.02 |
백준 알고리즘 14502[BFS, 배열] - 연구소 (0) | 2017.08.30 |
백준 알고리즘[배열] 14500 - 테트로미노 (0) | 2017.08.29 |
백준[단순 계산]13458 - 시험감독 (0) | 2017.08.28 |