IT recording...
[BOJ] 14891 톱니바퀴 - Java 본문
https://www.acmicpc.net/problem/14891
[문제 풀이]
- 역시 삼성의 구현 문제 답게 별 알고리즘은 필요없고 문제 꼼꼼히 읽고 구현하는 문제
- 정말 별로다 너무 디버깅이 힘들다 ㅜㅜ
- 나는 톱니가 1,4번이면 각각 2번,3번만 체크하면 되고 2,3번이면 각각 1,3번, 2,4번을 체크해야 하는 것을 보고 재귀 짤바에야 톱니 4개밖에 없으니까 그냥 if문으로 각각 경우 다 해주는게 나을것같다고 생각했다.
- 근데 주의할점, 이렇게 로직이 비슷한 경우에는 복붙을 사용하게 되는데 변수 정말 꼼꼼하게 살펴보고 붙여넣자..
(이번에도 복붙하다가 숫자 안바꾼 것이 있어서 디버깅에 애 먹었다..)
- 배열을 옮길까 하다가 그러면 시간초과 날 것 같아서 인덱스를 관리하기로 했다.
(근데 너무 복잡하다.)
- 시계방향으로 돌렸다면 원래 index1자리에 있던 것이 2로 이동한다.
내가 시계방향(1)으로 돌린 후 N번 자리에 있는 값을 얻고자 한다. 그러면 그 값은 8에서 온 값이기 때문에 , 원래 톱니의 N-1 을 찾아야 한다.
예를 들면 시계방향(1)으로 돌린 후 3번 자리에 있는 값을 얻고자 하면, 3-1=2, 즉 원래 톱니의 2번째 값을 취하면 된다.
원래 톱니 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
시계방향 (sawDir) | 8 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
반시계방향 (sawDir) | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1 |
- 그래서 sawDir이라는 배열을 만들어 시계방향으로 회전하면 -1을 더하고, 반시계방향으로 회전하면 1을 더한다. (왜 반대인지 이해가 안간다면 표를 다시 살펴보자. 시계방향으로 돈 후 3번 자리에 있는 2는 원래 2번 자리에 있던 애였다. 그래서 이 2를 얻기 위해 -1을 하는 것이다.)
- 그리고 M번째 톱니바퀴의 N번 자리에 있는 값을 얻고자 할 때 N+sawDir[M] 을 통해 원하는 값을 얻으면 된다.
[코드]
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Boj14891_톱니바퀴 {
static StringTokenizer st;
static int K;
static int[][] Saw = new int[4+1][8+1]; //Saw[i][j] : 톱니바퀴 i번째의 j번째 톱니
static int[] sawDir = new int [4+1];
static int answer;
public static void main(String[] args) throws Exception{
System.setIn(new FileInputStream("src/main/java/input.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
for(int i=1;i<5;i++){
String string = br.readLine();
for(int j=0;j<string.length();j++){
Saw[i][j+1] = Integer.parseInt(String.valueOf(string.charAt(j)));
}
}
K = Integer.parseInt(br.readLine());
//==========
for(int i=0;i<K;i++){
st = new StringTokenizer(br.readLine());
int sawNum = Integer.parseInt(st.nextToken()); //0:N극, 1:S극
int dir = Integer.parseInt(st.nextToken()); //1:시계방향 , -1:반시계방향
//바뀌기 전에 비교 후 1,2,3,4 각각 무슨 방향으로 돌지 확인해야함 -> sawDir[i] 설정
int one_3 = getPos(1,3+sawDir[1]);
int one_7 = getPos(1,7+sawDir[1]); //사실 필요없음
int two_3 = getPos(2,3+sawDir[2]);
int two_7 = getPos(2,7+sawDir[2]);
int three_3 = getPos(3,3+sawDir[3]);
int three_7 = getPos(3,7+sawDir[3]);
int four_3 = getPos(4,3+sawDir[4]); //사실 필요없음
int four_7 = getPos(4,7+sawDir[4]);
if(sawNum == 1){ //톱니바퀴 1번
sawDir[1] += dir * (-1);
if(one_3 != two_7){ //둘이 다르면 방향 바꾸기
dir *= -1;
}
else{
dir = 0; //같으면 그 이후로 안움직임
}
sawDir[2] += dir * (-1);
if(two_3 != three_7){
dir *= -1;
}
else{
dir = 0;
}
sawDir[3] += dir * (-1);
if(three_3 != four_7){
dir *= -1;
}
else{
dir = 0;
}
sawDir[4] += dir * (-1);
}
//2 -> 1 , 2 -> 3 -> 4
else if(sawNum == 2){
sawDir[2] += dir * (-1); //시계방향이면 -1, 반시계방향이면 1을 더함
//2 -> 1
int twoToOne = 0;
if(one_3 != two_7){ //둘이 다르면 방향 바꾸기
twoToOne = dir * -1;
}
sawDir[1] += twoToOne * (-1);
//2 -> 3 -> 4
if(two_3 != three_7){
dir *= -1;
}
else{ //같으면 그 이후로 안움직임
dir = 0;
}
sawDir[3] += dir * (-1);
if(three_3 != four_7){
dir *= -1;
}
else{
dir = 0;
}
sawDir[4] += dir * (-1);
}
//3 -> 2 -> 1 , 3 -> 4
else if(sawNum == 3){
sawDir[3] += dir * (-1); //시계방향이면 -1, 반시계방향이면 1을 더함
//3 -> 4
int threeToFour = 0;
if(three_3 != four_7){
threeToFour = dir * -1;
}
sawDir[4] += threeToFour * (-1);
//3 -> 2 -> 1
if(two_3 != three_7){ //둘이 다르면 방향 바꾸기
dir *= -1;
}
else{ //같으면 그 이후로 안움직임
dir = 0;
}
sawDir[2] += dir * (-1);
if(one_3 != two_7){
dir *= -1;
}
else{
dir = 0;
}
sawDir[1] += dir * (-1);
}
//4 -> 3 -> 2 -> 1
else{
sawDir[4] += dir * (-1); //시계방향이면 -1, 반시계방향이면 1을 더함
if(three_3 != four_7){
dir *= -1;
}
else{
dir = 0;
}
sawDir[3] += dir * (-1);
if(two_3 != three_7){
dir *= -1;
}
else{
dir = 0;
}
sawDir[2] += dir * (-1);
if(one_3 != two_7){ //둘이 다르면 방향 바꾸기
dir *= -1;
}
else{
dir = 0;
}
sawDir[1] += dir * (-1);
}
}
//다 돌림, 점수 계산 고고
getScore();
System.out.println(answer);
}
static void getScore(){
for(int i=1;i<5;i++){
int value = getPos(i,1+sawDir[i]); //1(12시방향)에 있는 값
if(value==1){ //S극이면
answer += Math.pow(2,i-1);
}
}
}
static int getPos(int sawNum, int p){
int pos = p % 8;
if(pos == 0){ //나머지가 0이면 8로
pos = 8;
}
else if(pos < 0){ //나머지가 음수면 ex) 나머지가 -1이면 7이 나와야 한다.
pos *= -1;
pos = 8 - pos;
}
return Saw[sawNum][pos]; //Saw의 pos1칸을 확인하면 값을 얻을 수 있음
}
}
[풀이 시간]
3h 정도 걸렸다.
디버깅이 너무 오래걸린다. 하나라도 잘못 짜면 디버깅만 한세월..
조건을 충분히 검토하고, 로직 짠 후에 키보드 잡는 연습하자
'Algorithm' 카테고리의 다른 글
[BOJ] 14889 스타트와링크 - Java (0) | 2022.04.13 |
---|---|
[BOJ] 15683 감시 - Java (0) | 2022.04.12 |
[BOJ] 14890 경사로 - Java (0) | 2022.04.08 |
[PG] 정수삼각형 - Java (0) | 2022.03.29 |
[PG] 전화번호목록 - Java (0) | 2022.03.28 |