티스토리 뷰
https://www.acmicpc.net/problem/17822
문제
반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀있고, i번째 원판에 적힌 j번째 수의 위치는 (i, j)로 표현한다. 수의 위치는 다음을 만족한다.
- (i, 1)은 (i, 2), (i, M)과 인접하다.
- (i, M)은 (i, M-1), (i, 1)과 인접하다.
- (i, j)는 (i, j-1), (i, j+1)과 인접하다. (2 ≤ j ≤ M-1)
- (1, j)는 (2, j)와 인접하다.
- (N, j)는 (N-1, j)와 인접하다.
- (i, j)는 (i-1, j), (i+1, j)와 인접하다. (2 ≤ i ≤ N-1)
아래 그림은 N = 3, M = 4인 경우이다.
원판의 회전은 독립적으로 이루어진다. 2번 원판을 회전했을 때, 나머지 원판은 회전하지 않는다. 원판을 회전시킬 때는 수의 위치를 기준으로 하며, 회전시킨 후의 수의 위치는 회전시키기 전과 일치해야 한다.
다음 그림은 원판을 회전시킨 예시이다.
원판을 아래와 같은 방법으로 총 T번 회전시키려고 한다. 원판의 회전 방법은 미리 정해져 있고, i번째 회전할때 사용하는 변수는 xi, di, ki이다.
- 번호가 xi의 배수인 원판을 di방향으로 ki칸 회전시킨다. di가 0인 경우는 시계 방향, 1인 경우는 반시계 방향이다.
- 원판에 수가 남아 있으면, 인접하면서 수가 같은 것을 모두 찾는다.
- 그러한 수가 있는 경우에는 원판에서 인접하면서 같은 수를 모두 지운다.
- 없는 경우에는 원판에 적힌 수의 평균을 구하고, 평균보다 큰 수에서 1을 빼고, 작은 수에는 1을 더한다.
원판을 T번 회전시킨 후 원판에 적힌 수의 합을 구해보자.
유형 : 구현
접근 방식
- 배열 돌리기 : 한칸씩 돌리지 말고 한번에 모든 칸을 돌리도록 구현
- 반시계 방향 : 반시계 방향을 시계 방향으로 돌리도록 변환 (한반향으로만 생각하는게 편하다)
- 같은 수 찾기 : 배열의 크기가 50 * 50이기 때문에 반복문으로 해결
- 0으로는 나눌 수 없다. (모든 칸이 사라진 경우 0으로 나누기 로직은 Error)
코드
import java.util.*;
import java.io.*;
public class BOJ_17822_원판_돌리기 {
static int n,m,t;
static int[][] board;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
t = Integer.parseInt(st.nextToken());
board = new int[n+1][m+1];
for(int i = 0 ; i < n ; i++) {
st = new StringTokenizer(br.readLine()," ");
for(int j = 0 ; j < m ; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i = 1 ; i <= t ; i++) {
st = new StringTokenizer(br.readLine()," ");
int x = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
turn(x,d,k);
}
int sum = 0;
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
sum += board[i][j];
}
}
System.out.println(sum);
br.close();
}
static void turn(int x,int d,int k) {
go(x,d,k);
erase();
}
static void erase() {
boolean find = false;
boolean[][] v = new boolean[n+1][m+1];
int sum = 0;
int count = 0;
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
if(board[i][j] == 0)
continue;
sum += board[i][j];
count += 1;
int v1 = j - 1 < 0 ? m - 1 : j - 1;
int v2 = j + 1 == m ? 0 : j + 1;
if(board[i][j] == board[i][v1] || board[i][j] == board[i][v2]) {
v[i][j] = true;
find = true;
}
if(i + 1 < n && board[i][j] == board[i+1][j]) {
v[i][j] = true;
find = true;
}
if(i - 1 >= 0 && board[i][j] == board[i-1][j]) {
v[i][j] = true;
find = true;
}
}
}
if(find) {
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
if(v[i][j]) {
board[i][j] = 0;
}
}
}
}else {
if(count != 0) {
double tt = (double) sum / count;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 0)
continue;
if ((double)board[i][j] > tt)
board[i][j] -= 1;
else if ((double)board[i][j] < tt)
board[i][j] += 1;
}
}
}
}
}
static void go(int x, int d, int k) {
int[][] tmp = new int[n+1][m+1];
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
tmp[i][j] = board[i][j];
}
}
for(int i = x - 1; i < n ; i+=x) {
if(d == 0) {
for(int j = 0 ; j < m ; j++) {
int next = (j + k) % m;
tmp[i][next] = board[i][j];
}
}else {
int tt = m - k%m;
for(int j = 0 ; j < m ; j++) {
int next = (j + tt) % m;
tmp[i][next] = board[i][j];
}
}
}
board = tmp;
}
static void print(int[][] board) {
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
System.out.print(board[i][j]+" ");
}
System.out.println();
}
System.out.println();
}
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 19538 (루머) - java (0) | 2024.12.03 |
---|---|
백준 19951 (태상이의 훈련소 생활) - java (0) | 2024.12.03 |
백준 1430 (공격) - java (0) | 2024.10.07 |
백준 28018 (시간이 겹칠까?) - java (1) | 2024.09.26 |
백준 6506 (엘 도라도) - java (2) | 2024.09.25 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 백준 #3980 #선발 명단
- 백준 #2580 #스도쿠
- 백준 #25195 #yes or yes #java #자바
- 백준 #12014 #주식 #자바 #java
- 백준 #인구 이동 #16234
- 백준 #1727 #커플 만들기 #자바 #java
- 17218
- 백준 #1987 #알파벳 #자바 #java
- 백준 #28140 #빨강~ 빨강~ 파랑! 파랑! 달콤한 솜사탕! #java #자바
- 백준 #1759 #암호 만들기
- 백준 #25603 #짱해커 이동식 #java #자바
- Java
- 백준 #다리 만들기 #2146
- 백준 #18405 #경쟁적 전염
- 백준 #1584 #게임 #java #자바
- 백준 #치즈 #2638
- 백준 #13549 #숨바꼭질3
- 자바
- 백준 #16973 #직사각형 탈출
- 백준 #2636 #치즈
- 백준 #
- 백준 #1325 #효율적인 해킹
- 백준 #5721 #사탕 줍기 대회 #java #자바
- 백준
- 17394
- 백준 #17940 #주식 #자바 #java
- 백준 #15686 #치킨 배달
- 백준 #14863 #서울에서 경산까지 #java #자바
- 자바 #JAVA
- 백준 #4963 #섬의 개수
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함