[백준 알고리즘, ] 삼성 코딩 테스트 문제 :: 14891번 톱니바퀴 자바 풀이
- -
이 문제는 BOJ 14891번 톱니바퀴 문제에요
문제만 잘 이해한다면 그리 어렵지는 않은것 같은데 시간이 좀 걸렸어요 ㅠㅠ
세 번만에 성공했네요...
문제는 아래 사이트에서 풀어보실 수 있어요
https://www.acmicpc.net/problem/14891
우선 회전을 시키기 전에 양 옆의 맞닿아있는 극의 상태를 확인해야 되요!!!
회전시킨뒤의 맞닿은 톱니의 극을 확인하는게 아닙니다!!
즉 돌릴 기어와 맞닿은 기어의 극을 돌리기전에 먼저 확인하고
기어의 극이 다르다면 그 기어의 옆을 연쇄적으로 확인해나가면 되요!!
그렇게 돌릴 기어들이 정해졌다면 그 정해진 기어들을 한 번에 돌리면 된답니다!!
그렇게 회전을 모두 시켜서 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)
<백준 온라인 저지 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];
}
}
'알고리즘 문제풀이 > BOJ' 카테고리의 다른 글
[백준 알고리즘, 시뮬레이션] 삼성 코딩 테스트 문제 :: 15686번 드래곤 커브 자바 풀이 (0) | 2019.10.30 |
---|---|
[백준 온라인 저지(BOJ), 브루트 포스] 삼성 코딩 테스트 문제 :: 15683번 감시 자바 풀이 (0) | 2019.10.28 |
[백준 알고리즘, 다이나믹 프로그래밍] 삼성 코딩 테스트 문제 기출 :: 14501번 퇴사 자바 풀이 (0) | 2019.10.26 |
[백준 알고리즘, 브루트 포스] 삼성 코딩 테스트 문제 :: 15686번 치킨 배달 자바 풀이 (0) | 2019.10.26 |
[백준 알고리즘, 브루트 포스, 순열] 삼성 SW 역량 테스트 문제 :: 14888번 연산자 끼워넣기 (0) | 2019.10.13 |
소중한 공감 감사합니다