https://www.acmicpc.net/problem/16937
16937번: 두 스티커
첫째 줄에 모눈종이의 크기 H, W, 둘째 줄에 스티커의 수 N이 주어진다. 다음 N개의 줄에는 스티커의 크기 Ri, Ci가 주어진다.
www.acmicpc.net
문제풀이
완전탐색 문제 + DFS + 아이디어 가 사용된 문제입니다.
문제푸는 방식입니다.
1. 문제를 보면 주어진 스티커를 90도로 회전하는 경우가 있습니다. 이를 고려하여 처음부터 스티커를 Node에 같이 넣어줍니다. 이떄 스티커 값을 넣을떄 주어진 그대로의 정보(Ri, Ci, 스티커 Index) 를 넣고, 90도 회전한 정보에 (Ci, Ri, 스티커 Index)를 넣습니다. 이떄 스티커 Index를 넣어주어야 이후에 완전탐색을 통해 모든 경우를 조사할때 같은 스티커를 같이 검사하지 않습니다.
2. 주어진 스티커 중 최대 2개의 스티커만 뽑아서 최대의 넓이를 구하기 위해 DFS를 활용하여 완전탐색을 진행합니다. 이 과정에서 1번과정에서 넣어준 StickerIndex를 사용하여 방문처리하여, 같은 스티커를 2번 뽑아서 사용하는 일이 없도록 합니다. 또한 선택된 스티커는 SelectedSticker[level]을 활용하여 SelectedSticker[0], SelectedSticker[1] 로써 관리합니다.
3. 만약 Level == 2 라면, 최대길이를 구하기 위해
3.1 가로로 배치한경우 ( 가로길이는 W보다 작거나 같고, 세로길이는 두개의 SelectedSticker[0], SelectedSticker[1] 중 최대의 높이만 H 보다 작거나 같으면 됩니다. ) 그리고서 스티커의 넓이는 구해서 더합니다.
3.2 세로로 배치한경우 ( 세로길이는 H보다 작거나 같고, rkfh길이는 두개의 SelectedSticker[0], SelectedSticker[1] 중 최대의 가로만 W 보다 작거나 같으면 됩니다. ) 그리고서 스티커의 넓이는 구해서 더합니다.
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static int H, W; public static int N; public static ArrayList<Node> Node = new ArrayList<Node>(); public static boolean[] visited; public static Node[] SelectedSticker = new Node[2]; //2개의 선택된 스티커 사용 public static int result = 0; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); H = Integer.parseInt(st.nextToken()); W = Integer.parseInt(st.nextToken()); st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); visited = new boolean[N]; for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); int R = Integer.parseInt(st.nextToken()); int C = Integer.parseInt(st.nextToken()); Node.add(new Node(R, C, i)); if( R != C) { //90도 회전까지 넣습니다. Node.add(new Node(C, R, i)); } } simulate(0, 0); System.out.println(result); } public static void simulate(int idx, int level) { if(level == 2) { //가로로 배치할때 ( 세로길이는 Sticker중 가장 긴것만 고려합니다. ) if(SelectedSticker[0].c + SelectedSticker[1].c <= W && Math.max(SelectedSticker[0].r, SelectedSticker[1].r) <= H) { result = Math.max(result, SelectedSticker[0].r * SelectedSticker[0].c + SelectedSticker[1].r * SelectedSticker[1].c); } //세로로 배치할때 ( 가로길이는 Sticker중 가장 긴것만 고려합니다. ) if(SelectedSticker[0].r + SelectedSticker[1].r <= H && Math.max(SelectedSticker[0].c, SelectedSticker[1].c) <= W) { result = Math.max(result, SelectedSticker[0].r * SelectedSticker[0].c + SelectedSticker[1].r * SelectedSticker[1].c); } return ; } for(int i=idx;i<Node.size();i++) { Node temp = Node.get(i); int R = temp.r; int W = temp.c; int TEMPSTICKERINDEX = temp.stickerIndex; if(visited[TEMPSTICKERINDEX] == true) continue; //중복된 스티커가 사용되지 않도록 처리합니다. visited[TEMPSTICKERINDEX] = true; SelectedSticker[level] = temp; //Sticker의 순서에 맞춰 넣습니다. simulate(i + 1,level + 1); SelectedSticker[level] = null; //Sticker를 사용햇다면 제거합니다. visited[TEMPSTICKERINDEX] = false; } } } class Node{ int r; int c; int stickerIndex; public Node(int r, int c, int stickerIndex) { this.r = r; this.c = c; this.stickerIndex = stickerIndex; } }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 14620 꽃길 - 완전탐색 JAVA (0) | 2023.07.15 |
---|---|
[백준] 16508 전공책 - 완전탐색 + 문자열(알파벳) JAVA (0) | 2023.07.14 |
[백준] 17626 Four Squares - 동적계획법(DP, Dynamic Programming) JAVA (0) | 2023.07.13 |
[백준] 2503 숫자 야구 - 완전탐색(DFS) + 아이디어 JAVA (0) | 2023.07.12 |
[백준] 16439 치킨치킨치킨 - 완전탐색(DFS) JAVA (0) | 2023.07.12 |