일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 이젠 골드구현도 어렵네..
- 01BFS
- 다이나믹프로그래밍
- 알고리즘
- 백준
- 다익스트라
- 시뮬레이션
- java
- 재귀함수
- 엘라스틱서치
- QUICKSTARTGUIDE
- 취득후기
- COSPRO
- COSPROJAVA1급
- dp
- spring
- 구현
- PS
- BFS
- 백준코딩테스트
- YBMCOS
- DFS
- deque
- 우선순위큐
- 세그먼트트리
- 자바PS
- 네트워크플로우
- 게더타운시작
- GatherTown
- 완전탐색
- Today
- Total
공부공간
BOJ - 17822 ) 원판 돌리기 본문
https://www.acmicpc.net/problem/17822
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
www.acmicpc.net
N개의 층이 있는 원판을 M등분하여, 각층에 숫자를 넣고, K번의 회전연산을 통하여 답을 구하는 문제이다.
각 회전연산마다 이웃한것끼리 같은것이면 ( 인접하면 ) 그수는 제거할수있다.
만약 수를 제거할수 없는 상황에는 원판전체의 평균을 구하여 그 평균보다 크면 -1 , 작으면 +1 작업을 통하여
수를 바꾸어준다.
원판위에 숫자가 존재하기 때문에 Index의 맨 마지막과 첫번째는 인접하고,
N번째 층은 N-1번째 층과 세로로 인접, 1번째 층은 2번째층과 세로로인접 나머지 K번째 층은
K+1, K-1층과 인접해있다.
문제를 풀기위해서, 원판위에 적힌 숫자를 배열로 옮기고, 각 배열이 원판처럼 연결되어있다고 생각해서 풀었다.
가로, 세로의 인접을 확인하기위해서 코드가 길어졌지만, 반복문을 통해서 줄일 수있었다.
내가 생각한 순서는
1. K의 단계를 2차원 배열로 저장한다. 첫번째 요소는 Rotate할 Row의 값, 두번째는 시계방향인지?반시계인지?
세번째는 몇번 연산을 수행하는지?
2. K에서 첫번째를 가져와 Rotate연산을 수행한다.
3. 회전이 완료되면 이웃한 것 중에 인접한 것이 있는지 판단을 하고,
4.그러한 경우가 없을때에는 평균을 구해서 숫자를 변경해준다.
사실상 FOR문으로 풀수있었지만 상당히 신경써주어야할 부분이 많아서인지 정답률이 낮았던것 같다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N,M,K;
static int map[][];
static int Rotate[][];
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());
K = Integer.parseInt(st.nextToken());
map = new int[N+1][M+1];
for(int y = 1; y <=N ; y++) {
st = new StringTokenizer(br.readLine());
for(int x = 1; x<=M ; x++) {
map[y][x] = Integer.parseInt(st.nextToken());
}
}
Rotate = new int[K+1][4];
for(int y = 1 ; y<= K ; y++) {
st = new StringTokenizer(br.readLine());
Rotate[y][1] = Integer.parseInt(st.nextToken()); // xi 의 배수들이 대상으로
Rotate[y][2] = Integer.parseInt(st.nextToken()); // 0 시계 1 반시계
Rotate[y][3] = Integer.parseInt(st.nextToken()); // 횟수
}
for(int index = 1 ; index <= K ;index++) {
int x = Rotate[index][1]; int rdir =Rotate[index][2]; int rtime = Rotate[index][3];
for(int arr = x; arr <=N ; arr +=x ) {
RotateClock(arr,rdir,rtime);
}
// 회전완료 인접한것 체크
boolean adj = true;
boolean visit[][] = new boolean[N+1][M+1];
for(int i =1 ; i <=N ; i++) {
for(int j= 1; j <=M ; j++) {
if(map[i][j]==0) continue;
if( i == 1){
if(j ==1) {
if(map[i][j]==map[i][j+1]) {
visit[i][j] = true;
visit[i][j+1] = true;
}
if(map[i][j]==map[i][M]) {
visit[i][j] = true;
visit[i][M] = true;
}
}
else if( j == M) {
if(map[i][j]==map[i][1]) {
visit[i][j] = true;
visit[i][1] = true;
}
if(map[i][M-1]==map[i][M]) {
visit[i][M-1] = true;
visit[i][M] = true;
}
}
else {
if(map[i][j] == map[i][j-1]) {
visit[i][j] = true;
visit[i][j-1] = true;
}
if(map[i][j] == map[i][j+1]) {
visit[i][j] = true;
visit[i][j+1] = true;
}
} // row 체크
// col 체크
if(map[i][j] == map[i+1][j]) {
visit[i][j] = true;
visit[i+1][j] = true;
}
}
else if( i == N) {
if(j ==1) {
if(map[i][j]==map[i][j+1]) {
visit[i][j] = true;
visit[i][j+1] = true;
}
if(map[i][j]==map[i][M]) {
visit[i][j] = true;
visit[i][M] = true;
}
}
else if( j == M) {
if(map[i][j]==map[i][1]) {
visit[i][j] = true;
visit[i][1] = true;
}
if(map[i][M-1]==map[i][M]) {
visit[i][M-1] = true;
visit[i][M] = true;
}
}
else {
if(map[i][j] == map[i][j-1]) {
visit[i][j] = true;
visit[i][j-1] = true;
}
if(map[i][j] == map[i][j+1]) {
visit[i][j] = true;
visit[i][j+1] = true;
}
}
if(map[i][j] == map[i-1][j]) {
visit[i][j] = true;
visit[i-1][j] = true;
}
}
else {
if(j ==1) {
if(map[i][j]==map[i][j+1]) {
visit[i][j] = true;
visit[i][j+1] = true;
}
if(map[i][j]==map[i][M]) {
visit[i][j] = true;
visit[i][M] = true;
}
}
else if( j == M) {
if(map[i][j]==map[i][1]) {
visit[i][j] = true;
visit[i][1] = true;
}
if(map[i][M-1]==map[i][M]) {
visit[i][M-1] = true;
visit[i][M] = true;
}
}
else {
if(map[i][j] == map[i][j-1]) {
visit[i][j] = true;
visit[i][j-1] = true;
}
if(map[i][j] == map[i][j+1]) {
visit[i][j] = true;
visit[i][j+1] = true;
}
}
if(map[i][j] == map[i-1][j]) {
visit[i][j] = true;
visit[i-1][j] = true;
}
if(map[i][j] == map[i+1][j]) {
visit[i][j] = true;
visit[i+1][j] = true;
}
}
}
}
for(int i =1 ; i <=N ; i++) {
for(int j= 1; j <=M ; j++) {
if(visit[i][j]) {
map[i][j] =0;
adj = false;
}
}
}
if(adj) {
// 평균을 구하고 큰건 -1 작은건 +1 ..
double avg =0; int sum =0; int cnt =0;
for(int i = 1 ; i <= N ; i ++) {
for(int j = 1 ; j <= M ; j++) {
if(map[i][j] !=0) {
sum+= map[i][j]; cnt++;
}
}
}
avg = ((double)sum)/(cnt);
for(int i = 1 ; i <= N ; i ++) {
for(int j = 1 ; j <= M ; j++) {
if(map[i][j]!=0) {
if( map[i][j] > avg ) {
map[i][j] -= 1;
}
else if( map[i][j] < avg ){
map[i][j] +=1;
}
}
}
}
}
}
int res =0;
for(int y =1 ; y <=N ; y++) {
for(int x= 1; x <=M ; x++) {
res += map[y][x];
}
}
System.out.print(res);
}
public static void RotateClock(int Row, int dir , int time) {
while(time > 0) {
if(dir == 0) { // 시계방향
int last = map[Row][M];
for(int index = M; index >1; index--) {
map[Row][index] = map[Row][index-1];
}
map[Row][1] = last;
}
else { // 반대
int first = map[Row][1];
for(int index = 1; index <M; index++) {
map[Row][index] = map[Row][index+1];
}
map[Row][M] = first;
}
time--;
}
}
}
'알고리즘 > 구현,시뮬' 카테고리의 다른 글
BOJ- 17143 ) 낚시왕 (0) | 2020.02.26 |
---|---|
SWEA - 5648 ) 원자소멸 시뮬레이션 (4) | 2020.02.23 |
BOJ - 17779 ) 게리맨더링 2 (0) | 2020.02.18 |
JUNGOL - 1828 ) 냉장고 (0) | 2020.02.13 |
Algorithm 풀이를 위한 JAVA 자료구조 정리 (2) | 2020.02.10 |