[백준] 12100 2048(Easy)
삼성 역태 준비중!
2048 게임 한창 열심히 하던거라 문제 설렁설렁 읽고 짰다가 수정의 늪에 빠져버린 문제 ㅠㅠ
중복되는 코드가 많은데 따로 함수로 뺄까 하다가 귀찮아서 그냥….
import java.util.*;
import java.io.*;
public class Main{
static int max;
static int n;
// 왼쪽으로 이동시 변경된 배열을 반환하는 함수
static int[][] left(int[][] a){
// 일단 복사
int[][] b = new int[n][n];
for(int i = 0 ; i < n ; i++){
System.arraycopy(a[i], 0, b[i], 0, n);
}
for(int i = 0 ; i < n ; i++ ){
for(int j = 0 ; j < n-1 ; j++){
if(b[i][j] != 0){ // 0 이 아닌 원소를 발견했다!
for(int k = j+1 ; k < n ; k++){ // 옆을 쭉 확인하며
if(b[i][k] == 0)continue; // 0 이면 건너뛰고
else if(b[i][j] == b[i][k]){ // 같은 숫자인 원소가 있다면
b[i][j] *= 2; b[i][k] = 0; break; // 원래 원소 값 *= 2, 다른값 = 0, 탐색 빠져나옴
}else break; // 0은 아닌데 같은 숫자가 아니라면 애초에 합쳐질리 없다
}
}
}
}
// 공백 제거
for(int i = 0 ; i < n ; i++){
ArrayList<Integer> temp = new ArrayList<>(); // 여기에 담을거다
for(int j = 0 ; j < n ; j++){ // 쭉 확인하면서 0이 아닌 숫자를 담아
if(b[i][j] != 0){
temp.add(b[i][j]);
}
b[i][j] = 0; // 초기화
}
for(int j = 0 ; j < temp.size() ; j++){
b[i][j] = temp.get(j); // 담은 순서대로 이쁘게 다시 배열로 담자
}
}
return b;
}
// 나머지 함수도 위랑 같은 원리다. 중복되는게 많아서 줄이려면 줄일 순 있으나
// 그럼 나중에 해석하기 힘들것 같아서 최대한 쉽게 풀어쓴 버전으로 둔다
// 사실 귀찮아서 그렇다(...)
static int[][] right(int[][] a){
int[][] b = new int[n][n];
for(int i = 0 ; i < n ; i++){
System.arraycopy(a[i], 0, b[i], 0, n);
}
for(int i = 0 ; i < n ; i++ ){
for(int j = n-1 ; j >= 1 ; j--){
if(b[i][j] != 0){
for(int k = j-1 ; k >= 0 ; k--){
if(b[i][k] == 0)continue;
else if(b[i][j] == b[i][k]){
b[i][j] *= 2; b[i][k] = 0; break;
}else break;
}
}
}
}
for(int i = 0 ; i < n ; i++){
ArrayList<Integer> temp = new ArrayList<>();
for(int j = n-1 ; j >= 0 ; j--){
if(b[i][j] != 0){
temp.add(b[i][j]);
}
b[i][j] = 0;
}
for(int j = 0 ; j < temp.size() ; j++){
b[i][n-j-1] = temp.get(j);
}
}
return b;
}
static int[][] up(int[][] a){
int[][] b = new int[n][n];
for(int i = 0 ; i < n ; i++){
System.arraycopy(a[i], 0, b[i], 0, n);
}
for(int i = 0 ; i < n ; i++ ){
for(int j = 0 ; j < n-1 ; j++){
if(b[j][i] != 0){
for(int k = j+1 ; k < n ; k++){
if(b[k][i] == 0)continue;
else if(b[j][i] == b[k][i]){
b[j][i] *= 2; b[k][i] = 0; break;
}else break;
}
}
}
}
for(int i = 0 ; i < n ; i++){
ArrayList<Integer> temp = new ArrayList<>();
for(int j = 0 ; j < n ; j++){
if(b[j][i] != 0){
temp.add(b[j][i]);
}
b[j][i] = 0;
}
for(int j = 0 ; j < temp.size() ; j++){
b[j][i] = temp.get(j);
}
}
return b;
}
static int[][] down(int[][] a){
int[][] b = new int[n][n];
for(int i = 0 ; i < n ; i++){
System.arraycopy(a[i], 0, b[i], 0, n);
}
for(int i = 0 ; i < n ; i++ ){
for(int j = n-1 ; j >= 1 ; j--){
if(b[j][i] != 0){
for(int k = j-1 ; k >= 0 ; k--){
if(b[k][i] == 0)continue;
else if(b[j][i] == b[k][i]){
b[j][i] *= 2; b[k][i] = 0; break;
}else break;
}
}
}
}
for(int i = 0 ; i < n ; i++){
ArrayList<Integer> temp = new ArrayList<>();
for(int j = n-1 ; j >= 0 ; j--){
if(b[j][i] != 0){
temp.add(b[j][i]);
}
b[j][i] = 0;
}
for(int j = 0 ; j < temp.size() ; j++){
b[n-j-1][i] = temp.get(j);
}
}
return b;
}
// 재귀함수 역할을 해줄 함수
// 경우의 수는 매 시도당 4개 인데, 총 5회 움직이므로 끽해서 4^5 = 1024 -> 재귀 고고!
static void go(int[][] a, int idx){
if(idx == 5){
int m = 0;
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(a[i][j] > m){
m = a[i][j];
}
}
}
if(m > max){
max = m;
}
return;
}
go(left(a), idx+1);
go(right(a), idx+1);
go(up(a), idx+1);
go(down(a), idx+1);
}
public static void main(String []args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
int[][] map = new int[n][n];
for(int i = 0 ; i < n ; i++){
StringTokenizer st = new StringTokenizer(br.readLine());
for(int j = 0 ; j < n ; j++ ){
map[i][j] = Integer.parseInt(st.nextToken());
}
}
max = 0;
go(map, 0);
System.out.println(max);
}
}
Comments