백준 16235[자바] java 나무 재테크
문제 링크: https://www.acmicpc.net/problem/16235
16235번: 나무 재테크
부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터
www.acmicpc.net
▶문제
부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1 ×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터 떨어진 칸의 개수, c는 가장 왼쪽으로부터 떨어진 칸의 개수이다. r과 c는 1부터 시작한다.
상도는 전자통신공학과 출신답게 땅의 양분을 조사하는 로봇 S2D2를 만들었다. S2D2는 1×1 크기의 칸에 들어있는 양분을 조사해 상도에게 전송하고, 모든 칸에 대해서 조사를 한다. 가장 처음에 양분은 모든 칸에 5만큼 들어있다.
매일매일 넓은 땅을 보면서 뿌듯한 하루를 보내고 있던 어느 날 이런 생각이 들었다.
나무 재테크를 하자!
나무 재테크란 작은 묘목을 구매해 어느 정도 키운 후 팔아서 수익을 얻는 재테크이다. 상도는 나무 재테크로 더 큰돈을 벌기 위해 M개의 나무를 구매해 땅에 심었다. 같은 1 ×1 크기의 칸에 여러 개의 나무가 심어져 있을 수도 있다.
이 나무는 사계절을 보내며, 아래와 같은 과정을 반복한다.
봄에는 나무가 자신의 나이만큼 양분을 먹고, 나이가 1 증가한다. 각각의 나무는 나무가 있는 1×1 크기의 칸에 있는 양분만 먹을 수 있다. 하나의 칸에 여러 개의 나무가 있다면, 나이가 어린 나무부터 양분을 먹는다. 만약, 땅에 양분이 부족해 자신의 나이만큼 양분을 먹을 수 없는 나무는 양분을 먹지 못하고 즉시 죽는다.
여름에는 봄에 죽은 나무가 양분으로 변하게 된다. 각각의 죽은 나무마다 나이를 2로 나눈 값이 나무가 있던 칸에 양분으로 추가된다. 소수점 아래는 버린다.
가을에는 나무가 번식한다. 번식하는 나무는 나이가 5의 배수이어야 하며, 인접한 8개의 칸에 나이가 1인 나무가 생긴다. 어떤 칸 (r, c)와 인접한 칸은 (r-1, c-1), (r-1, c), (r-1, c+1), (r, c-1), (r, c+1), (r+1, c-1), (r+1, c), (r+1, c+1)이다. 상도의 땅을 벗어나는 칸에는 나무가 생기지 않는다.
겨울에는 S2D2가 땅을 돌아다니면서 땅에 양분을 추가한다. 각 칸에 추가되는 양분의 양은 A[r][c]이고, 입력으로 주어진다.
K 년이 지난 후 상도의 땅에 살아있는 나무의 개수를 구하는 프로그램을 작성하시오.
▶입력
첫째 줄에 N, M, K가 주어진다.
둘째 줄부터 N개의 줄에 A배열의 값이 주어진다. r번째 줄의 c번째 값은 A [r][c]이다.
다음 M개의 줄에는 상도가 심은 나무의 정보를 나타내는 세 정수 x, y, z가 주어진다. 처음 두 개의 정수는 나무의 위치 (x, y)를 의미하고, 마지막 정수는 그 나무의 나이를 의미한다.
▶출력
첫째 줄에 K 년이 지난 후 살아남은 나무의 수를 출력한다.
▶해설
시뮬레이션 문제입니다. 계절 순서대로 주어진 조건을 수행하면 됩니다.
1. 봄 조건
- 나무는 나이가 적은 것들부터 흡수한다.
- 나무는 나이만큼 칸의 양분을 흡수한다. (나이가 1 증간한다.)
- 남은 양분이 나이보다 적다면 바로 죽는다.
private static void spring(){ List<Tree> tempT = new ArrayList<>(); for(Tree tree: trees){ if(map[tree.x][tree.y]-tree.age>=0){ map[tree.x][tree.y]-=tree.age; tempT.add(new Tree(tree.y,tree.x,tree.age+1)); } else{ dead.add(new Tree(tree.y,tree.x,tree.age)); } } trees = tempT; }
1. 자라는 나무와 죽은 나무를 구별하기 위해서 List를 하나 더 선언합니다.
2. 새로 선언한 List는 자라는 나무를 넣어줍니다.
3. Queue를 사용하여 죽은 나무를 담습니다.
4. 자라는 나무와 죽은 나무의 판별이 끝났다면 살아남은 나무로 trees를 바꿔줍니다.
2. 여름 조건
- 죽은 나무들의 나이/2만큼 해당 칸의 양분으로 더해진다.
private static void summer(){ while(!dead.isEmpty()) { Tree poll = dead.poll(); map[poll.x][poll.y] += (poll.age) / 2; } }
1. 죽은 나무들을 담아놨던 Queue를 하나씩 꺼내면서 더해줍니다.
3. 가을 조건
- 나무의 나이가 5의 배수인 것들에 한해서 8방향으로 나무의 나이가 1인 것을 심어준다.
private static void fall() { List<Tree> tempT = new ArrayList<>(); int[] y = {1, 1, 0, -1, -1, -1, 0, 1}, x = {0, 1, 1, 1, 0, -1, -1, -1}; for (Tree tree : trees) { if (tree.age % 5 == 0) { for (int i = 0; i < 8; i++) { int ny = tree.y + y[i]; int nx = tree.x + x[i]; if (ny >= 1 && ny <= n && nx >= 1 && nx <= n) { tempT.add(new Tree(ny, nx, 1)); } } } } trees.addAll(0, tempT); trees.sort((a,b) -> { return a.age-b.age; }); }
1. 새로 생기는 나무를 담을 List와 8방향에 대한 배열을 선업 합니다.
2. 기존에 심었던 나무들이 5의 배수인지 판별하고, 맞다면 기존의 틀에 넘지 않는 값들에 한해서 새로 나무를 심습니다.
3. 새로 심은 나무들을 원래 List에 더해주고 정렬해줍니다.
4. 겨울 조건
로봇이 양분을 새로 뿌려줍니다.
private static void winter(){ for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ map[i][j] += robot[i][j]; } } }
5. 최종 살아있는 나무 개수 구하기
System.out.println(trees.size());
아직 살아있는 나무들의 size를 출력해줍니다.
전체 코드
import java.io.*; import java.util.*; class Tree{ int y; int x; int age; public Tree(int y, int x, int age) { this.y = y; this.x = x; this.age = age; } } public class Main { static int n,m,k; static int [][] map, robot; static List<Tree> trees; static Queue<Tree> dead; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] s1 = br.readLine().split(" "); n = Integer.parseInt(s1[0]); m = Integer.parseInt(s1[1]); k = Integer.parseInt(s1[2]); robot = new int[n+1][n+1]; map = new int[n+1][n+1]; trees = new ArrayList<>(); dead = new ArrayDeque<>(); for(int i=1; i<=n; i++){ String[] s = br.readLine().split(" "); for(int j=1; j<=n; j++){ robot[i][j] = Integer.parseInt(s[j-1]); map[i][j] = 5; } } int y,x,age; for(int i=0; i<m; i++){ String[] s = br.readLine().split(" "); x = Integer.parseInt(s[0]); y = Integer.parseInt(s[1]); age = Integer.parseInt(s[2]); trees.add(new Tree(y,x,age)); } trees.sort((a,b) -> { return a.age-b.age; }); for(int i=0; i<k; i++){ simulation(); if(trees.isEmpty()){ System.out.println(0); return; } } System.out.println(trees.size()); } private static void simulation(){ spring(); summer(); fall(); winter(); } private static void spring(){ List<Tree> tempT = new ArrayList<>(); for(Tree tree: trees){ if(map[tree.x][tree.y]-tree.age>=0){ map[tree.x][tree.y]-=tree.age; tempT.add(new Tree(tree.y,tree.x,tree.age+1)); } else{ dead.add(new Tree(tree.y,tree.x,tree.age)); } } trees = tempT; } private static void summer(){ while(!dead.isEmpty()) { Tree poll = dead.poll(); map[poll.x][poll.y] += (poll.age) / 2; } } private static void fall() { List<Tree> tempT = new ArrayList<>(); int[] y = {1, 1, 0, -1, -1, -1, 0, 1}, x = {0, 1, 1, 1, 0, -1, -1, -1}; for (Tree tree : trees) { if (tree.age % 5 == 0) { for (int i = 0; i < 8; i++) { int ny = tree.y + y[i]; int nx = tree.x + x[i]; if (ny >= 1 && ny <= n && nx >= 1 && nx <= n) { tempT.add(new Tree(ny, nx, 1)); } } } } trees.addAll(0, tempT); trees.sort((a,b) -> { return a.age-b.age; }); } private static void winter(){ for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ map[i][j] += robot[i][j]; } } } }
'Alogorithm > simulation' 카테고리의 다른 글
백준 15685 [자바] java 드래곤 커브 (0) | 2022.02.05 |
---|---|
백준 17144 [자바] java 미세먼지 안녕! (0) | 2022.01.08 |
백준 JAVA 14891번 톱니바퀴 (0) | 2021.12.04 |
댓글
이 글 공유하기
다른 글
-
백준 15685 [자바] java 드래곤 커브
백준 15685 [자바] java 드래곤 커브
2022.02.05문제 링크: https://www.acmicpc.net/problem/15685 15685번: 드래곤 커브 첫째 줄에 드래곤 커브의 개수 N(1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 드래곤 커브의 정보가 주어진다. 드래곤 커브의 정보는 네 정수 x, y, d, g로 이루어져 있다. x와 y는 드래곤 커 www.acmicpc.net ▶문제 드래곤 커브는 다음과 같은 세 가지 속성으로 이루어져 있으며, 이차원 좌표 평면 위에서 정의된다. 좌표 평면의 x축은 → 방향, y축은 ↓ 방향이다. 시작 점 시작 방향 세대 0세대 드래곤 커브는 아래 그림과 같은 길이가 1인 선분이다. 아래 그림은 (0, 0)에서 시작하고, 시작 방향은 오른쪽인 0세대 드래곤 커브이다. 1세대 드래곤 커브는 0세대 … -
백준 17144 [자바] java 미세먼지 안녕!
백준 17144 [자바] java 미세먼지 안녕!
2022.01.08문제 링크: https://www.acmicpc.net/problem/17144 17144번: 미세먼지 안녕! 미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사 www.acmicpc.net ▶ 문제 미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r, c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r, c)는 r행 c열을 의미한다. 공기청정기는 항상 1번 열에 설치되… -
백준 JAVA 14891번 톱니바퀴
백준 JAVA 14891번 톱니바퀴
2021.12.04문제 링크: https://www.acmicpc.net/problem/14891 14891번: 톱니바퀴 총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴 www.acmicpc.net 시뮬레이션 문제로서 하나의 톱니바퀴를 돌렸을 때 옆에 있는 톱니바퀴들이 돌아간다면 상태 배열을 변경시키고 상태 배열에 따라서 시계방향, 반시계방향으로 돌려주면된다. 시작 지점에서의 시계, 반시계 방향으로 퍼져나가는 것을 생각해주면 어려운 문제는 아니다. import java.util.*; import java.io.*; class info{ int num; int dir; publ…
댓글을 사용할 수 없습니다.