알고리즘(Algorithm)의 종류, 분류/시뮬레이션(Simulation)

[JAVA]SWEA_특이한 자석

Miiko 2021. 10. 2. 14:20

https://swexpertacademy.com/main/talk/solvingClub/problemView.do?contestProbId=AWIeV9sKkcoDFAVH&solveclubId=AXqh7JhKC0QDFAV2&problemBoxTitle=%ED%92%80%EC%96%B4%EB%B4%85%EC%8B%9C%EB%8B%A4.&problemBoxCnt=29&probBoxId=AXqh7JhKC0UDFAV2 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

 

 

| 문제 해결방법

 

시뮬레이션 문제

 

처음에는 마지막 요소 -> 맨 앞으로 이동 또는 맨 앞 요소 -> 마지막 요소로 이동 의 연산 문제를 해결하기 위해 Deque을 사용하려고 했었다. 

 

문제는 자석이 4개이고 Deque배열을 만들어야 했기 때문에 다른 방법을 생각해보았다.

 

 

다른 방법으로, 

String 문자열을 생각했다.

문자열 특성상 index로 문자를 식별하고 연산을 할 수 있기 때문에 이 방법 선택. 

 

 

 

| 회전 여부를 체크

 

입력받은 자석을 기준으로 

'오른쪽', '왼쪽'을 나누어서 검사

 

'오른쪽'의 경우

기준 자석 문자열의 2번째 문자와 

기준 자석의 오른쪽 문자열의 6번째 문자가 

같은 경우 = 0 (이동 안함) -> 이동을 하지 않는 자석의 그 다음 자석들도 회전하지 X

다른 경우 = 기준 자석의 회전 방향의 반대 ( 기준 자석의 회전 방향 x -1 )

 

1 : 왼쪽 자석의 2번째 문자 / 0 : 오른쪽 자석의 6번째 문자

'왼쪽' 

위와 동일

 

 

 

 

| 회전 과정

 

자석을 '시계 방향', '반시계 방향'으로 돌리는 과정

 

- 시계 방향 : 0번째 문자를 7번째로 이동

 

 

- 반시계 방향 : 7번째 문자를 0번째로 이동

 

 

[JAVA] 해설 코드

package simulation;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class SWEA_magnet {

	static String[] q;
	static int N,score;
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		StringBuilder sb = new StringBuilder();
		int T = Integer.parseInt(br.readLine());
		for(int tc = 1; tc <=T; tc++) {
			

			q = new String[5]; 
			N =  Integer.parseInt(br.readLine());
			
			for(int i=1;i<=4;i++) {
				st = new StringTokenizer(br.readLine());
				String s = "";
				for(int j=0;j<8;j++) {
					s += Integer.parseInt(st.nextToken());
				}
				q[i] = s;
			}

			// N번 수행
			for(int i=0;i<N;i++) {
				
				st = new StringTokenizer(br.readLine());
				int start = Integer.parseInt(st.nextToken());
				int dir = Integer.parseInt(st.nextToken());
                    		// 1 : 시계방향, -1 : 반시계방향, 0 : 회전X
				int[] turn = new int[5];
				
				
				// 회전 여부 체크
				int tempStart = start; // 회전 기준점
				int tempDir = dir; // 기준점의 회전 방향 
                		// 기준점의 회전 방향 저장
				turn[start] = dir; 

				//오른쪽
				while(tempStart<4) {
					int l = q[tempStart].charAt(2)-'0';
					int r = q[tempStart+1].charAt(6)-'0';
					
					// 다르면 반대방향
					if(r!=l) {
						tempDir = tempDir*-1;
						turn[tempStart+1] = tempDir;
					}else {
						turn[tempStart+1]=0;
						break;
					}
					tempStart++;
				}
				
				
				// 왼쪽 회전 여부 체크 시 재초기화
				tempStart = start;
				tempDir = dir;
				//왼쪽
				while(tempStart>1) {
					int r = q[tempStart].charAt(6)-'0';
					int l = q[tempStart-1].charAt(2)-'0';
					// 다르면 반대방향
					if(r!=l) {
						tempDir = tempDir*-1;
						turn[tempStart-1] = tempDir;
					}else {
						turn[tempStart-1]=0;
						break;
						
					}
					tempStart--;
				}
				
				
				
				// 회전
				for(int t=1;t<5;t++) {
					String s = q[t];
					String ns = "";
					// 시계방향
					if(turn[t]==1) {
						ns += s.charAt(7);						
						ns += s.substring(0,7);
						q[t]=ns;
					}
					// 반 시계
					else if(turn[t]==-1) {
						ns += s.substring(1,8);
						ns += s.charAt(0);
						q[t]=ns;
					}
				}

			}
			
			
			score = 0;
			int n=1;
			for(int t=1;t<5;t++) {
				if(q[t].charAt(0) == '1') {
					score += Math.pow(2, t-1); // 점수는 위치 순서대로 1,2,4,8 점 
				}
			}
			
			
			sb.append("#"+tc+" ").append(score).append("\n");
		}

		System.out.println(sb.toString());
	}

}

 

 

[제출] 메모리 및 시간