-
[JAVA] 4013번 : 특이한 자석 (SWEA) & 14891번 : 톱니바퀴 (BOJ)Java 2024. 5. 11. 13:29
입출력 형식만 다르고 사실상 같은 문제라서 같이 적어보는 졸린김에 잠깰겸 적는 풀이 히힛
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeV9sKkcoDFAVH
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
처음에 제출했을 때는 계속 터져버렸다
그리고 이후에 답을 그냥 보고 이해하는 식으로 풀었다.
사실 답 보고 금방 이해했다. 그냥 머릿속에 있는걸 코드로 표현을 못하는게 문제였기 때문이다...
[Java/자바 swea 4013] 특이한 자석
풀이 처음 스택을 쓰려고 했는데 엄청 복잡했습니다... 그래서 2차원 배열을 통해 구현했습니다. map 4x8 2차원 형태로 저장하구 , arr에 시계면 1, 반시계면 -1, 회전 하지않는다면 0 으로 담았습니다
kwangkyun-world.tistory.com
1. solve 함수
방향 배열에 각 상태에 따라 방향을 담는다.
방향을 담아야 해당 방향에 맞게 자석을 돌리기 때문!
그림을 보면 idx 를 1에서 시작한다면 현재 자석은 3, 다음 자석은 7번이랑 비교하게 된다. (idx 를 0에서 시작한다면 현재 자석은 2, 다음 자석은 6이겠죵)
static void solve(int x, int d) { dArr[x] = d; // 받아온 방향 // 오른쪽으로 회전 for(int i=x+1;i<4;i++) { if(map[i][6]==map[i-1][2]) { break; } else dArr[i] = -dArr[i-1]; } // 왼쪽으로 회전 for(int i=x-1;i>=0;i--) { if(map[i][2]==map[i+1][6]) { break; } else dArr[i] = -dArr[i+1]; } rotation(); }
처음에 내가 생각했던건 배열을 담아야지 보다는 그냥 변수로 두고 함수로 빼려고 했다.
// 처음 : 화살표 위치 static void solve(int x, int d){ // S극 : 1 // N극 : 0 // 시계 : 1, 반시계 : -1 // idx : 3이랑 7 이랑 물려 있음 // 1. idx 에 물려 있는 값 먼저 확인 // x 랑 x+1 // 2. 값이 다르면 서로 다른 극 // 3. 서로 반대 방향 으로 회전 boolean res[] = new boolean[4]; for(int i=1;i<=3;i++) { // 다른 지 같은 지 결과 배열에 저장 // 1, 2 (3, 7) // 2, 3 (3, 7) // 3, 4 (3, 7) if(map[i][3]!=map[i+1][7]) { res[i] = true; // 다르면 true }else { res[i] = false; // 같으면 false } } // 나 기준 전, 후 확인 // 다음 꺼랑 비교 할때 -> 내가 3 다음 꺼가 7 // 이전 꺼랑 비교 할때 -> 내가 7 이전 꺼가 3 // 다르면 그때 if(x==1) { if(res[x]) { rotation(x, d); rotation(x+1, -d); if(res[x+1]) { rotation(x+2, d); if(res[x+2]) { rotation(x+3, -d); } } } }else if(x==2) { if(res[x-1]) { // 1 rotation(x-1, -d); rotation(x, d); if(res[x]) { // 2 rotation(x+1, -d); if(res[x+1]) { // 3 rotation(x+2, d); } } } }else if(x==3) { if(res[x-1]) { rotation(x-1, -d); rotation(x, d); if(res[x-2]) { rotation(x-2, d); } if(res[x]) { rotation(x+1, -d); } } }else { if(res[x-1]) { rotation(x-1, -d); rotation(x, d); if(res[x-2]) { rotation(x-2, -d); if(res[x-3]) { rotation(x-3, d); } } } } }
이렇게 아주 비효율적인 만약에 코드를 생각했었다 바보.
2. rotation 함수
// 회전 static void rotation() { for(int i=0;i<4;i++) { if(dArr[i]==0) continue; else if(dArr[i]==1) { // 시계 방향 회전 int tmp = map[i][7]; for(int y=7;y>=1;y--) { map[i][y] = map[i][y-1]; } map[i][0]=tmp; }else if(dArr[i]==-1){ // -1 // 반시계 방향 회전 int tmp = map[i][0]; for(int y=0;y<=6;y++) { map[i][y] = map[i][y+1]; } map[i][7]=tmp; } } }
그리고 회전하는것도 코드를 잘못 작성했었는데, 이전꺼를 다음꺼에 넣거나 다음꺼를 현재꺼에 넣어야하는데, 난 반대로 했었다. 아래처럼....하면 기존 값을 넣는게 아니라 이미 바뀌어진 값을 넣는거라 그냥 값이 이상하게 나온다.
// map 회전 static void rotation(int x, int d) { // x : 행 번호 // 시계 if(d==1) { // 1. 마지막 값을 tmp 에 저장 int tmp = map[x][8]; // 2. 한 칸 식 오른쪽 for(int y=1;y<=7;y++) { map[x][y+1] = map[x][y]; } // 3. tmp 에 저장한 값 처음에 다시 저장 map[x][1] = tmp; }else { // 반시계 // 반시계 // 1. 처음 값을 tmp 에 저장 int tmp = map[x][1]; // 2. 한 칸 씩 왼쪽 for(int y=8;y>=2;y--) { map[x][y-1] = map[x][y]; } // 3. tmp 에 저장한 값 마지막에 다시 저장 map[x][8] = tmp; }
쨋든 이 2개의 함수를 이용하면 쉽게 답을 구할수있었다!
그냥 방향 배열에 방향 담고 그 방향에 맞게 배열을 돌려주기만 하면 되는 문제! 전체 코드는 아래와 같다!
import java.io.*; import java.util.*; public class Solution { static int k, map[][], n, dir, dArr[], ans=0; public static void main(String[] args) throws Exception, IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; int T = Integer.parseInt(br.readLine()); for(int tc=1; tc<=T; tc++) { st = new StringTokenizer(br.readLine()); k = Integer.parseInt(st.nextToken()); map = new int[4][8]; ans = 0; for(int i=0;i<4;i++) { st = new StringTokenizer(br.readLine()); for(int j=0;j<8;j++) { map[i][j] = Integer.parseInt(st.nextToken()); } } for(int i=0;i<k;i++) { dArr = new int[4]; // 방향 배열 st = new StringTokenizer(br.readLine()); n = Integer.parseInt(st.nextToken()); dir = Integer.parseInt(st.nextToken()); solve(n-1, dir); } for(int i=0;i<4;i++) { if(map[i][0]==1) { // s 극 일때 ans+=Math.pow(2, i); // System.out.println(i); } } System.out.println("#" + tc + " " + ans); } } static void solve(int x, int d) { dArr[x] = d; // 받아온 방향 // 오른쪽으로 회전 for(int i=x+1;i<4;i++) { if(map[i][6]==map[i-1][2]) { break; } else dArr[i] = -dArr[i-1]; } // 왼쪽으로 회전 for(int i=x-1;i>=0;i--) { if(map[i][2]==map[i+1][6]) { break; } else dArr[i] = -dArr[i+1]; } rotation(); } // 0 1 2 3 4 5 6 7 // 0 0 1 0 0 1 0 0 // 회전 static void rotation() { for(int i=0;i<4;i++) { if(dArr[i]==0) continue; else if(dArr[i]==1) { // 시계 방향 회전 int tmp = map[i][7]; for(int y=7;y>=1;y--) { map[i][y] = map[i][y-1]; } map[i][0]=tmp; }else if(dArr[i]==-1){ // -1 // 반시계 방향 회전 int tmp = map[i][0]; for(int y=0;y<=6;y++) { map[i][y] = map[i][y+1]; } map[i][7]=tmp; } } } }
참고로 백준 문제는 "톱니바퀴"랑 동일한 문제였고! 입출력 형식만 아래처럼 다르게 하면 바로 정답이 나온다!
https://www.acmicpc.net/problem/14891
음음 무려 4일전이었군...제출이..
이걸 왜 이제 쓰고있는지
개미한테 부지런함을 배우자!
아차차 백준 전체 코드는 아래랑 같다!
import java.io.*; import java.util.*; class Main { static int k, map[][], ans, n, dir, arr[]; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; map = new int[5][9]; // 4개의 자석 for(int i=1;i<=4;i++) { String line = br.readLine(); // 각 자석은 8개의 '날' 을 가지고 있음 for(int j=0;j<8;j++) { map[i][j] = line.charAt(j) -'0'; } } st = new StringTokenizer(br.readLine()); k = Integer.parseInt(st.nextToken()); // k 번 회전 for(int i=0;i<k;i++) { arr = new int[5]; st = new StringTokenizer(br.readLine()); n = Integer.parseInt(st.nextToken()); // 몇 번 dir = Integer.parseInt(st.nextToken()); // 방향 solve(n , dir); // 회전 할 때마다 // map 은 공통 으로 활용 } ans = 0; // 1 번 -> N극 0점 S극 1점 (2 의 0승) // 2 번 -> N극 0점 S극 2점 (2 의 1승) // 3 번 -> N극 0점 S극 4점 (2 의 2승) // 4 번 -> N극 0점 S극 8점 (2 의 3승) for(int i=1;i<=4;i++) { if(map[i][0]==1) { // S극 일 때만 점수 ans+=Math.pow(2, i-1); } } // 임의의 자석 1 칸씩 k 번 회전 // 하나의 자석이 1칸 회전 될 때, System.out.println(ans); } // 처음 : 화살표 위치 // S극 : 1 // N극 : 0 // 시계 : 1, 반시계 : -1 static void solve(int x, int d){ arr[x] = d; // 방향 배열 // idx : 3이랑 7 이랑 물려 있음 // 1. idx 에 물려 있는 값 먼저 확인 // x 랑 x+1 // 2. 값이 다르면 서로 다른 극 // 3. 서로 반대 방향 으로 회전 // 오른쪽 for(int i=x+1;i<=4;i++) { if(map[i][6]==map[i-1][2]) { break; } else arr[i] = -arr[i-1]; } // 왼쪽 for(int i=x-1;i>=1;i--) { if(map[i+1][6]==map[i][2]) { break; } else arr[i] = -arr[i+1]; } rotation(); } // map 회전 static void rotation() { // x : 행 번호 for(int i=1;i<=4;i++) { if(arr[i]==0) continue; else if(arr[i]==1) { // 시계 // 1. 마지막 값을 tmp 에 저장 int tmp = map[i][7]; // 2. 한 칸 식 오른쪽 for(int y=7;y>=1;y--) { map[i][y] = map[i][y-1]; } // 3. tmp 에 저장한 값 처음에 다시 저장 map[i][0] = tmp; }else if(arr[i]==-1) { // 반시계 // 1. 처음 값을 tmp 에 저장 int tmp = map[i][0]; // 2. 한 칸 씩 왼쪽 for(int y=0;y<=6;y++) { map[i][y] = map[i][y+1]; } // 3. tmp 에 저장한 값 마지막에 다시 저장 map[i][7] = tmp; } } } }
'Java' 카테고리의 다른 글
[Java] 프로그래머스 - 모의고사 (1) 2024.10.23 [Java] 프로그래머스 - 최소 직사각형 (0) 2024.10.23 [Java] 메모리 구조 (1) 2024.01.27 [JAVA] 숫자와 문자 (0) 2024.01.02 [JAVA] 언어소개 & 프로그램 동작 (2) 2024.01.02