https://www.acmicpc.net/problem/17822
17822번: 원판 돌리기
반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀
www.acmicpc.net
저는 구현을 통해 문제를 해결하였습니다.
저는 2차원 배열을 통해 원판을 표현하여 인접한 것을 체크하기 용이하게 코드를 작성하였습니다.
package BOJ.simulation;
import java.awt.print.Pageable;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.StringTokenizer;
import java.util.function.Function;
public class BOJ_17822 {
private static final int EMPTY = 0;
private static final int CLOCKWISE = 0;
private static final int COUNTERCLOCKWISE = 1;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
Function<String,Integer> stoi = Integer::parseInt;
int n = stoi.apply(st.nextToken());
int m = stoi.apply(st.nextToken());
int t = stoi.apply(st.nextToken());
int[][] input = new int[n+1][m];
for(int i = 1 ; i <= n ; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0 ; j < m ; j++){
input[i][j] = stoi.apply(st.nextToken());
}
}
for(int i = 0 ; i < t; i++){
st = new StringTokenizer(br.readLine());
int x = stoi.apply(st.nextToken());
int d = stoi.apply(st.nextToken());
int k = stoi.apply(st.nextToken());
rotate(input,x,d,k,n,m);
checkNear(input,n,m);
}
System.out.println(calScore(input,n,m));
}
private static void print(int[][]input,int n,int m){
for(int i = 1 ; i <= n ; i++){
System.out.println(Arrays.toString(input[i]));
}
System.out.println();
}
private static int calScore(int[][] input, int n, int m) {
int sum = 0;
for(int i = 1 ; i <= n ; i++){
for(int j = 0 ; j < m ; j++){
sum += input[i][j];
}
}
return sum;
}
private static final int[] DY = {-1,0,1,0};
private static final int[] DX = {0,1,0,-1};
private static void checkNear(int[][] input, int n, int m) {
boolean[][] near = new boolean[n+1][m];
boolean findNear = false;
for(int i = 1 ; i <= n ; i++){
for(int j = 0 ; j < m ; j++){
for(int dir = 0 ; dir < 4; dir++){
int ny = i + DY[dir];
if(ny < 1 || ny > n) {
continue;
}
int nx = j + DX[dir];
if(nx < 0){
nx = m-1;
}
if(nx >= m){
nx = 0;
}
if(input[i][j] == input[ny][nx] && input[i][j] != EMPTY){
findNear = true;
near[i][j] = true;
near[ny][nx] = true;
}
}
}
}
if(!findNear){
int sum = 0;
int cnt = 0;
for(int i = 1 ; i <= n ; i++){
for(int j = 0 ; j < m ; j++){
if(input[i][j] != EMPTY){
cnt++;
sum += input[i][j];
}
}
}
double avg = (double)sum/cnt;
for(int i = 1 ; i <= n ; i++){
for(int j = 0 ; j < m ; j++){
if(input[i][j] == EMPTY){
continue;
}
if(input[i][j] > avg ){
input[i][j]--;
continue;
}
if(input[i][j] < avg){
input[i][j]++;
continue;
}
}
}
return;
}
for(int i = 1 ; i <= n ; i++){
for(int j = 0 ; j < m ; j++){
if(near[i][j]){
input[i][j] = EMPTY;
}
}
}
}
private static void rotate(int[][] input, int x, int d, int k, int n, int m) {
for(int i = 1 ; i <= n ; i++){
if(i % x == 0){
for(int a = 0 ; a < k ; a++){
if(d == CLOCKWISE){
int prev = input[i][m-1];
for(int j = 0 ; j < m ; j++){
int temp = input[i][j];
input[i][j] = prev;
prev = temp;
}
}else{
int prev = input[i][0];
for(int j = m-1 ; j >= 0 ; j--){
int temp = input[i][j];
input[i][j] = prev;
prev = temp;
}
}
}
}
}
}
}
'알고리즘' 카테고리의 다른 글
백준 1406번 에디터 (JAVA) (0) | 2022.08.10 |
---|---|
백준 14921번 용액 합성하기 (JAVA) (0) | 2022.08.09 |
벡즌 17090번 미로 탈출하기 (JAVA) (0) | 2022.08.07 |
백준 1713번 후보 추천하기 (JAVA) (0) | 2022.08.06 |
백준 13335번 트럭 (JAVA) (0) | 2022.08.05 |