톱니바퀴

링크

 

문제풀이

  • 나의 구현력을 테스트하는 문제이다.
  • 우선 톱니가 어떻게 돌아가는지 파악하는 것이 중요하다.
    • 같은 극을 띠고 있는 톱니가 맞물린다면 돌아가지 않는다.
    • 다른 극을 띠고 있는 톱니가 맞물린다면 돌아간다.
  • 나는 아래의 순서로 했다.
    • 현재 선택된 톱니바퀴를 기준점으로 잡고 좌 톱니, 우 톱니의 값을 인덱스 형태로 저장한다.
    • 현재 선택된 톱니바퀴를 기준으로 왼쪽의 톱니바퀴를 돌린다.
    • 현재 선택된 톱니바퀴를 기준으로 오른쪽의 톱니바퀴를 돌린다.
    • 톱니를 K번 돌리고나서 12시 방향에 있는 톱니의 극을 확인해서 score 값에 누적한다.
  • 구현력 혹은 시뮬레이션이라 부르는 문제들에 대해서 최대한 머릿속에 그려서 올바른 사고로 정확한 답을 도출해내는 연습이 필요함을 느낄 수 있다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class Main {

	static InputStreamReader isr;
	static BufferedReader br;
	static OutputStreamWriter osw;
	static BufferedWriter bw;
	static StringTokenizer st;
	
	public static void main(String[] args) throws IOException {

		isr = new InputStreamReader(System.in);
		br = new BufferedReader(isr);
		osw = new OutputStreamWriter(System.out);
		bw = new BufferedWriter(osw);

		String line = null;
		String[]values = new String[5];
		
		int[][]element = new int[5][2];
		for(int i = 0; i < 4; i++) {
			line = br.readLine();
			
			values[i+1] = line;
			element[i+1][0] = 6;
			element[i+1][1] = 2;
		}
		
		int K = Integer.parseInt(br.readLine());
		
		for(int i = 0; i < K; i++) {
			st =  new StringTokenizer(br.readLine());
			int number = Integer.parseInt(st.nextToken());
			int direction = Integer.parseInt(st.nextToken());
			
			int[]wheelInfo = element[number];
			
			/** 톱니는 8개다 **/
			boolean isRight = (direction == 1)? true : false;
			
			/** 회전하는 톱니의 왼쪽 부분과 오른쪽 부분 **/
			/** 미리 값을 가지고 있는다. **/
			int localLeftToothed = wheelInfo[0];
			int localRightToothed = wheelInfo[1];
			
			/** 톱니 위치는 변경 **/
			if(isRight) {
				/** 시계 **/
				wheelInfo[0] -= 1;
				wheelInfo[1] -= 1;
				
			}else {
				/** 반시계 **/
				wheelInfo[0] += 1;
				wheelInfo[1] += 1;
			}
			
			settingWheel(wheelInfo);
			element[number] = wheelInfo;
					
			int[][]standard = element;
			
			/** 왼쪽 : 왼쪽 톱니를 돌린다  **/
			for(int left = number - 1; left >= 1; left--) {
				int[]leftWheelInfo = standard[left];
				
				/** 값을 확인  **/
				if(values[left].charAt(leftWheelInfo[1]) == values[left+1].charAt(localLeftToothed)) {
					break;
				}else {
					if(isRight) {
						localLeftToothed = leftWheelInfo[0];
						
						/** 반시계방향 **/
						leftWheelInfo[0] += 1;
						leftWheelInfo[1] += 1;
						isRight = false;
					}else {
						localLeftToothed = leftWheelInfo[0];
						
						/** 시계방향 **/
						leftWheelInfo[0] -= 1;
						leftWheelInfo[1] -= 1;
						isRight = true;
					}
					
					settingWheel(leftWheelInfo);
					element[left] = leftWheelInfo;
				}
			}
			
			/** 현재 톱니가 돌아가는 방향을 다시 초기화해준다. 이전에 왼쪽 톱니 옮기면서 섞여있기 떄문에 **/
			isRight = (direction == 1)? true : false;
			
			/** 오른쪽 : 오른쪽 톱니 돌린다 **/
			for(int right = number + 1; right < 5; right++) {
				int[]rightWheelInfo = standard[right];
				
				if(values[right].charAt(rightWheelInfo[0]) == values[right-1].charAt(localRightToothed)) {
					break;
				}else {
					if(isRight) {
						localRightToothed = rightWheelInfo[1];
						
						/** 반시계방향 **/
						rightWheelInfo[0] += 1;
						rightWheelInfo[1] += 1;
						isRight = false;
					}else {
						localRightToothed = rightWheelInfo[1];
						
						/** 시계방향 **/
						rightWheelInfo[0] -= 1;
						rightWheelInfo[1] -= 1;
						isRight = true;
					}
					
					settingWheel(rightWheelInfo);
					element[right] = rightWheelInfo;
				}
			}
		}	
		
		int score = 0;
		
		/** score 획득하기  **/
		for(int n = 0; n < 4; n++) {
			int[]wheelInfo = element[n+1];
			
			/** 12시에 가리키는 값 **/
			int time = wheelInfo[0] + 2;
			time %= 8;
			
			if(values[n+1].charAt(time) == '0') {
				continue;
			}
			
			if(n == 0) {
				score += 1;
			} else if(n == 1) {
				score += 2;
			} else if(n == 2) {
				score += 4;
			} else {
				score += 8;
			}
		}
		
		bw.write(score + "\n");
		bw.flush();
		bw.close();
		br.close();
	}	
	
	
	/**
	 * 휠 조정 <p>
	 * @param wheelInfo
	 */
	private static void settingWheel(int[]wheelInfo) {
		if(wheelInfo[0] == 8) {
			wheelInfo[0] = 0;
		} 
		if(wheelInfo[0] == -1) {
			wheelInfo[0] = 7;
		} 
		if(wheelInfo[1] == 8) {
			wheelInfo[1] = 0;
		}
		if(wheelInfo[1] == -1) {
			wheelInfo[1] = 7;
		}
	}
}
Posted by doubler
,