광규니
광규니네
광규니
전체 방문자
오늘
어제
  • 분류 전체보기 (154)
    • 알고리즘 (100)
      • 알고리즘 개념 (2)
      • 문제 풀이 (96)
    • 주절주절 (19)
      • 자격증, 활동 후기 (4)
      • 전시회 후기 (3)
      • 이모저모 (2)
      • 회고 (3)
      • 뜨럼 (7)
    • 운영체제 (9)
    • 개발 지식 (9)
      • Apple Watch (4)
      • MySQL (2)
      • Eclipse (1)
      • XCode (1)
    • 네트워크 공부 (1)
    • 데이터베이스 공부 (5)
    • Java 공부 (7)
    • TMP (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 티스토리챌린지
  • BOJ
  • DP
  • 컴퓨터 사이언스
  • 알고리즘
  • 합주
  • 프로그래머스
  • OS
  • 개념
  • 운영체제
  • 백준
  • 구현
  • 오블완
  • 애플워치 앱
  • 파이썬
  • 드린이
  • 다이나믹 프로그래밍
  • 자바
  • BFS
  • 애플워치 앱 만들기

최근 댓글

최근 글

티스토리

250x250
hELLO · Designed By 정상우.
광규니

광규니네

알고리즘/문제 풀이

[Java/자바 백준 17822] 원판 돌리기

2022. 2. 17. 01:41
반응형

풀이

문제를 보면 원판이 있고, 문제도 길어서 어려워 보이지만,

사실 간단한 문제이다.

 

초기 값을 map에 입력 받고

 

1. 시계, 반시계 방향으로 몇 번 돌릴지

2. 인접한 숫자 중 같은 값이 있어주면 0으로 만들어주기

3. 인접한 숫자 중 같은 값이 없으면 평균 값을 구해 평균 값보다 크면 +1, 작으면 -1 해주는 문제

 

시계, 반시계는 forwardLotate(), reverseLotate()로 index를 하나씩 밀어주거나 땡겨주었다.

 

findEqualPoint()에서 bfs를 사용했는데, y값에 해당하는 값이 0 or M 값이 일때 조건을 줘 값을 바꿔주었다.

왜냐하면 원 형태이므로 순환하기 때문이다.

같은 값이 있으면 처리해서 point에 더해주었고

더한 point값 들을 total에서 빼주었다.

 

만약 point값이 0 이라면 onePlusMinus()에서 처리를 해주었다.

평균 값은 반올림을 하지 않으므로, float 타입으로 하여 평균값을 저장해주어 비교주었다.

 

import java.io.*;
import java.util.*;

public class Main {
	static int N, M, T, x, d, k, total, point, count;
	static int[][] map;	
	static Queue<int[]> queue = new LinkedList<int[]>();
	static boolean[][] visited;
	static int[] dx = {1,0,-1,0};
	static int[] dy = {0,1,0,-1};
	
	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());
		count = N * M;
		map = new int[N][M];
		
		for(int i = 0 ; i < N ; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0 ; j < M ; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				total += map[i][j];
			}
		}
		
		for(int i = 0 ; i < T ; i++) {
			st = new StringTokenizer(br.readLine());
			// x의 배수 
			x = Integer.parseInt(st.nextToken());
			// 0 이면 시계 1 이면 반시계 
			d = Integer.parseInt(st.nextToken());
			// k 칸 
			k = Integer.parseInt(st.nextToken());
			
			for(int j = 0 ; j < k ; j++) {
				if(d == 0) forwardLotate();
				else if(d == 1) reverseLotate();
			}
			
			visited = new boolean[N][M];
			point = 0;
			for(int row = 0 ; row < N ; row++) {
				for(int col = 0 ; col < M ; col++) {
					if(map[row][col] == 0) visited[row][col] = true;
					else if(visited[row][col] == false) findEqualPoint(row, col);
				}
			}
			
			total -= point;
			if(point == 0) onePlusMinus();
		}
		System.out.println(total);
	}
	
	private static void onePlusMinus() {
		float average = (float)total / count;
		
		for(int i = 0 ; i < N ; i++) {
			for(int j = 0 ; j < M ; j++) {
				if(map[i][j] == 0 ) continue;
				else if(map[i][j] > average) {
					map[i][j] -= 1;
					total -= 1 ;
				}
				else if(map[i][j] < average) {
					map[i][j] += 1;
					total += 1;
				}
			}
		}
	}

	private static void findEqualPoint(int x, int y) {
		visited[x][y] = true;
		queue.offer(new int[] {x, y});
		int samePoint = 0;
		int tmp = map[x][y];
		while(!queue.isEmpty()) {
			int[] cur = queue.poll();
			for(int i = 0 ; i < 4 ; i++) {
				int nx = cur[0] + dx[i];
				int ny = cur[1] + dy[i];
				
				if(0 > nx || nx >= N) continue;
				if(0 > ny) ny = M-1;
				if(ny >= M ) ny = 0;
				if(visited[nx][ny]) continue;
				
				if(map[nx][ny] == tmp) {
					visited[nx][ny] = true;
					queue.offer(new int[] {nx, ny});
					samePoint += map[nx][ny];
					count -= 1;
					map[nx][ny] = 0;
  				}
			}
		}
		if(samePoint > 0) {
			map[x][y] = 0;
			count -= 1;
			samePoint += tmp;
		}
		point += samePoint;
	}

	private static void reverseLotate() {
		int plus = x;
		for(int i = x-1 ; i < N ; i += plus) {
			int tmp = map[i][0];
			for(int j = 0 ; j < M-1 ; j++) {
				map[i][j] = map[i][j+1];
			}
			map[i][M-1] = tmp;
		}
	}

	private static void forwardLotate() {
		int plus = x ;
		for(int i = x - 1; i < N ; i += plus) {
			int tmp = map[i][M-1];
			for(int j = M-1 ; j > 0 ; j--) {
				map[i][j] = map[i][j-1];
			}
			map[i][0] = tmp;
		}
	}
}

 

반응형
저작자표시 (새창열림)

'알고리즘 > 문제 풀이' 카테고리의 다른 글

[Java/자바 백준 10655] 마라톤 1  (0) 2022.02.22
[Java/자바 백준 17825] 주사위 윷놀이  (0) 2022.02.17
[Java/자바 백준 17135] 캐슬 디펜스  (0) 2022.02.15
[Java/자바 백준 1347] 미로 만들기  (0) 2022.02.15
[Java/자바 백준 17837] 새로운 게임 2  (0) 2022.02.14
    '알고리즘/문제 풀이' 카테고리의 다른 글
    • [Java/자바 백준 10655] 마라톤 1
    • [Java/자바 백준 17825] 주사위 윷놀이
    • [Java/자바 백준 17135] 캐슬 디펜스
    • [Java/자바 백준 1347] 미로 만들기
    광규니
    광규니
    공부 및 일상 올리기~

    티스토리툴바