곽로그
[백준 17822 Java] 원판돌리기 본문
반응형
코드 더 간결하게
1. 실수한 부분
1) 배수 *x가 아니라 +x
2) board를 업데이트 할때 직접 board에 바로 업데이트 하는 경우 인접한 경우를 모두 못지움 -> boolean배열로 update가 있는지 확인하고 update가 있으면 지우기
3) 평균보다 큰거 +1, 작은거 -1 할때 이미 지워진 수를 제외하고 해야하는데 포함시킴
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static int[][] board;
public static int N;
public static int M;
public static int[][] command;
public static int T;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
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];
for(int r=1;r<=N;r++) {
st = new StringTokenizer(br.readLine(), " ");
for(int c=0;c<M;c++) {
board[r][c] = Integer.parseInt(st.nextToken());
}
}
command = new int[T][3];
for(int t = 0; t<T; t++) {
st = new StringTokenizer(br.readLine(), " ");
command[t][0] = Integer.parseInt(st.nextToken());
command[t][1] = Integer.parseInt(st.nextToken());
command[t][2] = Integer.parseInt(st.nextToken());
}
for(int c = 0 ;c<T; c++) {
int x = command[c][0];
int d = command[c][1];
int k = command[c][2];
solve(x,d,k);
}
int sum = 0;
for(int n =1 ;n<=N; n++) {
for(int index =0; index<M;index++) {
if(board[n][index]!=0) {
sum += board[n][index];
}
}
}
bw.write(String.valueOf(sum));
bw.flush();
}
public static void solve(int x, int d, int k) {
//x배수의 원판을 d(0:시계 1: 반시계) 방향으로 k번 회전해라
for(int number = x; number<=N ; number=number+x) {
rotate(number,d,k);
}
//인접한 수 지우기
boolean erase = false;
boolean[][] eraseBoared = new boolean[N+1][M];
for(int number =1; number<=N; number++) {
for(int index = 0; index<M; index++) {
int compareValue = board[number][index];
if(compareValue==0) {
continue;
}
int left = (index-1)<0?M-1: index-1;
int right = (index+1)>=M? 0 : index+1;
if(compareValue ==board[number][left]) {
erase = true;
eraseBoared[number][left] =true;
eraseBoared[number][index] =true;
}
if(compareValue == board[number][right]) {
erase = true;
eraseBoared[number][right] =true;
eraseBoared[number][index] =true;
}
int up = number+1;
if(up+1<=N) {
if(compareValue == board[up][index]) {
erase = true;
eraseBoared[up][index] =true;
eraseBoared[number][index] =true;
}
}
int down = number-1;
if(down>=1) {
if(compareValue == board[down][index]) {
erase = true;
eraseBoared[down][index] =true;
eraseBoared[number][index] =true;
}
}
}
}
if(erase) {
for(int n =1; n<=N;n++) {
for(int index = 0; index<M; index++) {
if(eraseBoared[n][index]) {
board[n][index] =0;
}
}
}
}
if(!erase) {
//평균 구하기
double sum = 0;
int count =0;
double avg = 0;
for(int n =1 ;n<=N; n++) {
for(int index =0; index<M;index++) {
if(board[n][index]!=0) {
count++;
sum += board[n][index];
}
}
}
avg = sum/count;
//평균보다 큰거 +1, 작은거 -1
for(int n =1 ;n<=N; n++) {
for(int index =0; index<M;index++) {
if(board[n][index]!=0) {
if(board[n][index]>avg) {
board[n][index]--;
}
else if(board[n][index]<avg){
board[n][index]++;
}
}
}
}
}
}
public static void rotate(int number, int d, int k) {
//number번호의 원판을 d 방향으로 k번 회전
int[] newBoard = new int[M];
if(d==0) {
for(int index =0; index<M; index++) {
int n = (index+ k)%(M);
newBoard[n] = board[number][index];
}
}
else if(d==1){
for(int index =0; index<M; index++) {
int n = (index+ M- k)%M;
newBoard[n] = board[number][index];
}
}
for(int index=0;index<M;index++) {
board[number][index] = newBoard[index];
}
}
public static void printMap(int[][] map) {
for(int r=0; r<map.length;r++) {
for(int c=0;c<map[r].length;c++) {
System.out.print(map[r][c]+" ");
}
System.out.println();
}
}
}
반응형
Comments