문제풀이/구현

[JAVA] [구현] 백준 15898 피아의 아틀리에

승무_ 2023. 6. 30. 15:34

문제

https://www.acmicpc.net/problem/15898

 

15898번: 피아의 아틀리에 ~신비한 대회의 연금술사~

"피아의 아틀리에 ~신비한 대회의 연금술사~"는 가난한 연금술사 피아의 성장스토리를 담은 게임이다. 이 게임의 가장 중요한 부분은 "대회"인데, 연금술로 높은 품질의 물건을 만들어 상금을 타

www.acmicpc.net

코드

import java.io.*;
import java.util.*;

public class b15898 {
    static ArrayList<String> permu=new ArrayList<>();

    public static class Point{
        int v;  // 품질
        char c;  // 색
        Point(int v, char c){
            this.v=v;
            this.c=c;
        }
    }
    
    // 순열 구하는 함수
    public static void per(int n, int cur, String s, boolean visited[]){
        if(cur==3){
            permu.add(s);
            return;
        }
        for (int i=0; i<n; i++){
            if(visited[i] == false){
                visited[i]=true;
                per(n,cur+1,s+i,visited);
                visited[i]=false;
            }
        }
         
    }

    // 90도 회전 함수
    public static Point[][] rotate90(Point[][] map){
        Point[][] temp=new Point[4][4];
        for(int i=0; i<4; i++){
            for(int j=0; j<4; j++){
                temp[i][j]=map[3-j][i];
            }
        }
        return temp;
    }

    // 시작 위치 구하는 함수
    public static String startPoint(int k){
        if(k==0) return "00";
        else if(k==1) return "01";
        else if(k==2) return "10";
        else return "11";
    }

    public static int cal(Point[][] map1, int j1, int k1, Point[][] map2, int j2, int k2, Point[][] map3, int j3, int k3, Point[][] resultmap){
        // j번 회전
        for(int i=0; i<j1; i++){
            map1=rotate90(map1);
        }

        // k를 통해 시작위치 구함
        int r=(int)startPoint(k1).charAt(0)-'0';
        int c=(int)startPoint(k1).charAt(1)-'0';

        // 가마 초기화
        for (int i=0; i<5; i++){
            for (int j=0; j<5; j++){
                resultmap[i][j].v=0;
                resultmap[i][j].c='W';
            }
        }

        for (int i=r; i<r+4; i++){
            for (int j=c; j<c+4; j++){
                if (resultmap[i][j].v + map1[i-r][j-c].v < 0){
                    resultmap[i][j].v=0;
                }
                else if (resultmap[i][j].v + map1[i-r][j-c].v > 9){
                    resultmap[i][j].v=9;
                }
                else {
                    resultmap[i][j].v += map1[i-r][j-c].v;
                }
                if(map1[i-r][j-c].c=='W') continue;
                else{
                    resultmap[i][j].c=map1[i-r][j-c].c;
                }
            }
        }

        for(int i=0; i<j2; i++){
            map2=rotate90(map2);
        }

        r=(int)startPoint(k2).charAt(0)-'0';
        c=(int)startPoint(k2).charAt(1)-'0';

        for (int i=r; i<r+4; i++){
            for (int j=c; j<c+4; j++){
                if (resultmap[i][j].v + map2[i-r][j-c].v < 0){
                    resultmap[i][j].v=0;
                }
                else if (resultmap[i][j].v + map2[i-r][j-c].v > 9){
                    resultmap[i][j].v=9;
                }
                else {
                    resultmap[i][j].v += map2[i-r][j-c].v;
                }
                if(map2[i-r][j-c].c=='W') continue;
                else{
                    resultmap[i][j].c=map2[i-r][j-c].c;
                }
            }
        }

        for(int i=0; i<j3; i++){
            map3=rotate90(map3);
        }

        r=(int)startPoint(k3).charAt(0)-'0';
        c=(int)startPoint(k3).charAt(1)-'0';


        for (int i=r; i<r+4; i++){
            for (int j=c; j<c+4; j++){
                if (resultmap[i][j].v + map3[i-r][j-c].v < 0){
                    resultmap[i][j].v=0;
                }
                else if (resultmap[i][j].v + map3[i-r][j-c].v > 9){
                    resultmap[i][j].v=9;
                }
                else {
                    resultmap[i][j].v += map3[i-r][j-c].v;
                }
                if(map3[i-r][j-c].c=='W') continue;
                else{
                    resultmap[i][j].c=map3[i-r][j-c].c;
                }
            }
        }

        int answer=0;
        for (int i=0; i<5; i++){
            for (int j=0; j<5; j++){
                if(resultmap[i][j].c=='R'){
                    answer+=7*resultmap[i][j].v;
                }
                else if(resultmap[i][j].c=='B'){
                    answer+=5*resultmap[i][j].v;
                }
                else if(resultmap[i][j].c=='G'){
                    answer+=3*resultmap[i][j].v;
                }
                else if(resultmap[i][j].c=='Y'){
                    answer+=2*resultmap[i][j].v;
                }
            }
        }
        return answer;
    }


    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int n = Integer.parseInt(br.readLine());
        ArrayList<Point[][]> arr= new ArrayList<>();
        
        Point[][] result=new Point[5][5];
        for(int i=0; i<5; i++){
            for(int j=0; j<5; j++){
                result[i][j]=new Point(0,'W');
            }
        }

        int[][] tempA;
        char[][] tempB;
        Point[][] tempC;

        for(int t=0; t<n; t++){
            tempA=new int[4][4];
            for (int i=0; i<4; i++){
                st = new StringTokenizer(br.readLine());
                for(int j=0; j<4; j++){
                    tempA[i][j]=Integer.parseInt(st.nextToken());
                }
            }

            tempB=new char[4][4];
            for (int i=0; i<4; i++){
                st = new StringTokenizer(br.readLine());
                for(int j=0; j<4; j++){
                    tempB[i][j]=st.nextToken().charAt(0);
                }
            }
            tempC=new Point[4][4];
            for (int i=0; i<4; i++){
                for(int j=0; j<4; j++){
                    tempC[i][j]=new Point(tempA[i][j], tempB[i][j]);
                }
            }
            arr.add(tempC);
        }
        // Input End
        
        per(n,0,"",new boolean[n]);
        int answer=0;
        // 순열 경우의 수 만큼 반복
        for(int i=0; i<permu.size(); i++){
            Point[][] arr1=arr.get((int)permu.get(i).charAt(0)-'0');
            Point[][] arr2=arr.get((int)permu.get(i).charAt(1)-'0');
            Point[][] arr3=arr.get((int)permu.get(i).charAt(2)-'0');

            // 4(회전 가능한 수) x 4((0,0),(0,1),(1,0),(1,1)) x 4 x 4 x 4 x 4
            for(int j1=0; j1<4; j1++){
                for(int k1=0; k1<4; k1++){
                    for(int j2=0; j2<4; j2++){
                        for(int k2=0; k2<4; k2++){
                            for(int j3=0; j3<4; j3++){
                                for(int k3=0; k3<4; k3++){
                                    answer=Math.max(answer,cal(arr1,j1,k1,arr2,j2,k2,arr3,j3,k3,result));
                                }
                            }
                        }
                    }
                }
            }
        }

        System.out.println(answer);

    }
}