새소식

알고리즘 문제풀이/BOJ

[백준 알고리즘, ] 삼성 코딩 테스트 문제 :: 14891번 톱니바퀴 자바 풀이

  • -

이 문제는 BOJ 14891번 톱니바퀴 문제에요

문제만 잘 이해한다면 그리 어렵지는 않은것 같은데 시간이 좀 걸렸어요 ㅠㅠ

세 번만에 성공했네요...

 

문제는 아래 사이트에서 풀어보실 수 있어요

https://www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴가 1번, 그 오른쪽은 2번, 그 오른쪽은 3번, 가장 오른쪽 톱니바퀴는 4번이다. 이때, 톱니바퀴를 총 K번 회전시키려고 한다. 톱니바퀴의 회전은 한 칸을 기준으로 한다. 회전은 시계 방향과 반시계 방향이 있고, 아래 그림과 같이 회전한다. 톱니바퀴를 회전시키려

www.acmicpc.net

 

우선 회전을 시키기 전에 양 옆의 맞닿아있는 극의 상태를 확인해야 되요!!!

회전시킨뒤의 맞닿은 톱니의 극을 확인하는게 아닙니다!!

즉 돌릴 기어와 맞닿은 기어의 극을 돌리기전에 먼저 확인하고

기어의 극이 다르다면 그 기어의 옆을 연쇄적으로 확인해나가면 되요!!
그렇게 돌릴 기어들이 정해졌다면 그 정해진 기어들을 한 번에 돌리면 된답니다!!

 

그렇게 회전을 모두 시켜서 12시 방향의 극의 따라서 점수를 구해 출력하면 끝이에요

 

<코드 설명>

빠르게 푸는 연습을 하느라 코드 중에 필요 없거나 더 간단하게 할 수 있는 부분들이

존재할테니 그런 부분은 감안하고 로직 부분만 봐주시면 감사하겠습니다.

 

이 문제는 크게 회전판별과 회전으로 나뉘어져요

 

1. 회전 판별

입력을 모두 받고 rotate라는 함수를 통해서 풀이를 시작하게되요

저는 if문으로 모두 나누어서 계산했어요

i가 0이면 1번 톱니....3이면 4번 톱니 이런식으로 case를 나누어서 했어요

우선 gears 2차원 배열을 보면 gears[i][j] 는 i+1번째 기어를 의미하고 j는 0부터 시계방향으로 되요

[i][2]는 기어의 오른쪽 톱니, [i][6]은 기어의 왼쪽 톱니를 나타내요

if(i==0)안의 다음 if문은 이런 뜻이에요

1번째 톱니의 오른쪽과 2번쨰 톱니의 왼쪽이 다른 극이라면 기어를 돌리기로 하고

명령을 담은 comandList에 넣고 2번째와 3번쨰 톱니가 다른극인지 이렇게 순차적으로 확인해나가요

그렇게 모두 담고 마지막 for문에서 명령을 하나씩 꺼내서 돌려요

 

2. 회전

회전은 시계방향으로 회전 시키는 함수(rotateClockwise)와

시계반대 방향으로 회전 시키는 함수(rotateCounterClockwise)가 있어요

 

예를 들어 기어가 10101111 이렇게 되어 있다면(S극 : 1/N극 : 0)

시계방향으로 회전시키면 11010111이 되요

그림을 발로 그리긴 했지만... 그림을 보시면 이해가실 거에요 오른쪽으로 한 칸씩 밀린다는 것을요

그리고 맨 끝에 기어의 값이 맨 처음으로 와요

 

그러면 시계 반대방향은 반대로 움직이겠죠???

왼쪽으로 한 칸씩 밀리고 맨 처음의 인덱스(12시 방향 톱니)가 맨 끝으로 이동하게 되요

이를 이용해서 회전을 시켜주면 끝난답니다!!!

 

아래 코드 올려놓은 깃허브 주소도 올려놓을테니 참고하세요

https://github.com/wlgh325/BOJ_answer/tree/master/14891(Gear)

 

wlgh325/BOJ_answer

Contribute to wlgh325/BOJ_answer development by creating an account on GitHub.

github.com

 

<백준 온라인 저지 14891번 톱니 바퀴 자바 풀이>

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;

class Command{
	int dir;
	int num;

	Command(int dir, int num){
		this.dir = dir;
		this.num = num;
	}
}
class Main {
	static int[][] gears;	// 톱니바퀴
	static int[][] command;

	/*
	1번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 1점
	2번 톱니바퀴의 12시방향이 N극이면 0점,S극이면 2점
	3번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 4점
	4번 톱니바퀴의 12시방향이 N극이면 0점, S극이면 8점
	*/

	// 12시 방향부터 시계방향

	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int rotateNum;
		gears = new int[4][8];

		for(int i=0; i<4; i++){
			String input = br.readLine();
			String[] temp = input.split("");
			for(int j=0; j<8; j++){
				gears[i][j] = Integer.parseInt(temp[j]);
			}
		}

		rotateNum = Integer.parseInt(br.readLine());
		command = new int[rotateNum][2];
		for(int i=0; i<rotateNum; i++){
			String input2 = br.readLine();
			String[] temp2 = input2.split(" ");
			command[i][0] = Integer.parseInt(temp2[0]);
			command[i][1] = Integer.parseInt(temp2[1]);
		}

		for(int i=0; i<rotateNum; i++){
			rotate(command[i][0], command[i][1]);
		}

		int score = calScore();

		System.out.println(score);
	}
	
	static int calScore(){
		int score =1;
		int sum = 0;
		for(int i=0; i<4; i++){
			if(gears[i][0] == 1){
				sum += score;
			}
			score *= 2;
		}

		return sum;
	}

	static void rotate(int i, int dir){
		i -= 1;
		ArrayList<Command> arrList = new ArrayList<>();

		// 명령에 해당하는 톱니 바퀴 회전
		insertCommand(dir, arrList, i);

		// 해당 톱니바퀴 회전으로 인해 회전해야할 톱니바퀴 골라서 회전시키기
		if(i == 0){
			if(gears[i][2] != gears[i+1][6]){
				insertCommand(dir*-1, arrList, i+1);
				if(gears[i+1][2] != gears[i+2][6]){
					insertCommand(dir, arrList, i+2);
					if(gears[i+2][2] != gears[i+3][6]){
						insertCommand(dir*-1, arrList, i+3);
					}
				}
			}
		}
		else if(i==1){
			if(gears[i][6] != gears[i-1][2]){
				insertCommand(dir*-1, arrList, i-1);
			}
			
			if(gears[i][2] != gears[i+1][6]){
				insertCommand(dir*-1, arrList, i+1);
				if(gears[i+1][2] != gears[i+2][6]){
					insertCommand(dir, arrList, i+2);
				}
			}
		}
		else if(i==2){
			if(gears[i][2] != gears[i+1][6]){
				insertCommand(dir*-1, arrList, i+1);
			}
			if(gears[i][6] != gears[i-1][2]){
				insertCommand(dir*-1, arrList, i-1);
				if(gears[i-1][6] != gears[i-2][2]){					
					insertCommand(dir, arrList, i-2);
				}
			}
		}
		else if(i==3){
			if(gears[i][6] != gears[i-1][2]){
				insertCommand(dir*-1, arrList, i-1);
				if(gears[i-1][6] != gears[i-2][2]){
					insertCommand(dir, arrList, i-2);
					if(gears[i-2][6] != gears[i-3][2]){
						insertCommand(dir*-1, arrList, i-3);
					}
				}
			}
		}

		for(int j=0; j<arrList.size(); j++){
			if(arrList.get(j).dir == 1)
				rotateClockwise(arrList.get(j).num);
			else
				rotateCounterClockwise(arrList.get(j).num);
		}
	}

	static void insertCommand(int dir, ArrayList<Command> arrList, int i){
		Command command = new Command(dir, i);
		arrList.add(command);
	}

	// 시계방향 : 1
	// 반시계방향 : 0

	// 3번째 극이 물림
	// 10101111 시계회전 -> 11010111
	static void rotateClockwise(int i){
		int[] temp = new int[8];
		System.arraycopy(gears[i], 0, temp, 0, gears[i].length);
		
		gears[i][0] = temp[7];
		for(int j=0; j<7; j++){
			gears[i][j+1] = temp[j];
		}
		
	}

	//	01011111
	static void rotateCounterClockwise(int i){
		int[] temp = new int[8];
		System.arraycopy(gears[i], 0, temp, 0, gears[i].length);

		gears[i][7] = temp[0];
		for(int j=0; j<7; j++)
			gears[i][j] = temp[j+1];
	}
}
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.