[백준] 2840번: 행운의 바퀴

조승현·2024년 3월 6일

알고리즘

목록 보기
1/15
post-thumbnail

문제

https://www.acmicpc.net/problem/2840

사실 처음 문제를 보고 진짜 이해가 너무 안 됐다..
분명 쉽다고 들어서 문제를 딱 봤는데 설명이 너무 복잡하게 되어있어서 한참을 읽었다

그렇기에 내가 이해한 대로 다시 한 번 적어보려고 한다

  1. 처음에 입력되는 두 가지 숫자 (N, K) 중 N은 바퀴에 존재하는 칸의 개수, K는 그 바퀴를 돌리는 횟수를 의미한다
  2. K번 만큼 반복해서 사용자에게 입력을 받을 것이다 (2번째 줄부터 K+1번째 줄까지)
  3. S와 알파벳이 주어지는데 S는 돌아가는 칸의 수 그 옆의 알파벳은 S칸 만큼 간 후 있는 알파벳을 의미한다
  4. 혹시나 입력받은 값에 오류가 존재한다면 (같은 칸에 다른 문자가 존재, 한 문자가 여러 번 등장) !를 출력한다
  5. 그 외의 경우는 해당하는 알파벳을 출력한다
  6. 모르는 칸이 있다면 알파벳 대신 ?를 출력한다

예를 들어서

3 3
1 A
2 B
3 C

1번 칸에 A, (1+2 = 3) 3번 칸에 B, ((3+3)%3 + 1 = 1) 1번 칸에 C가 있다는 뜻이다.
근데 이는 A와 C가 같은 곳에 있다는 뜻이기에 모순이다.

결과적으로 출력되는 값은 !

알고리즘

3칸인 돌림판을 1칸 돌린 것, 4칸 돌린 것은 값이 같다 = 나머지 연산 사용

입력 받은 문자가 이미 돌림판에 존재하는지 확인 = Boolean 배열 선언 후 아스키 코드 값으로 각 문자 저장 후 true, false 값 바꾸기

이 두가지가 생각했을 때 가장 중요한 부분인 것 같다

추가
시계방향으로 간다는 사실!!
이것 때문에 결괏값이 자꾸 달라져서 한참 고민..
런타임 에러가 나기는 했지만 이는 나중에 보완하도록 하겠습니다.. ㅎㅎ

코드

전 자바가 편해서 자바로 코딩 했습니다

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

// 다시 확인
public class Baekjoon2840 {

	public static void main(String[] args) throws IOException{
		// TODO Auto-generated method stub
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		// 칸 수와 회전 수를 저장하는 변수 N, K
		String [] input = br.readLine().split(" ");
		int N = Integer.parseInt(input[0]);
		int K = Integer.parseInt(input[1]);
		
		// 회전판에 있는 문자를 저장하는 배열, 뭔지 모르면 기본값은 ?이기 때문에 ?로 배열 채우기
		char[] wheel = new char[N];
		Arrays.fill(wheel, '?');
		
		// 회전판에 문자가 존재하는지 확인하기 위한 배열
		boolean t[] = new boolean[26];
		Arrays.fill(t, false);
		
		// 가르키는 칸의 번호를 나타내는 변수 arrow
		int arrow = 0;
		
		// 모순이 발생했는지 확인하는 변수 check
		int check = 0;
		
		// 사용자에게 입력 받기
		for (int i=0 ; i<K ; i++) {
			String [] str = br.readLine().split(" ");
			int S = N - Integer.parseInt(str[0]);
			char alpha = str[1].charAt(0);
			
			arrow = (arrow + S) % N;
			
			// 이미 문자가 들어가있고 그 문자가 입력받은 문자와 다르다면 모순 발생
			if (wheel[arrow] != '?' && wheel[arrow] != alpha) {
				check = 1;
				break;
			}
			// 이미 다른 곳에서 alpha의 문자가 쓰였다면 모순 발생
			else if (wheel[arrow] != alpha && t[alpha -'A'] == true) {
				check = 1;
				break;
			}
			// 중복도 없고 ?에 들어갈 문자라면 배열에 문자열 대입 후, 중복 체크용 배열 true로 변환
			else {
				wheel[arrow] = alpha;
				t[alpha - 'A'] = true;
			}
		}
		
		// 만약 모순이 있는 경우라면 ! 출력
		if (check == 1) {
			System.out.println("!");
		}
		//모순이 없다면 화살표가 끝난 곳부터 하나씩 출력
		else {
			StringBuilder sb = new StringBuilder();
			for (int i=arrow ; i<N ; i++) {
				sb.append(wheel[i]);
			}
			for (int i=0 ; i<arrow ; i++) {
				sb.append(wheel[i]);
			}
			System.out.println(sb);
		}
	}

}

마무리

생각보다 경우의 수를 잘 나누면 그렇게 고통스러운 문제는 아니었다
그래도 시계방향에서 갑자기 멘붕이 와서 숫자를 이리저리 막 옮겨보았다
생각해보니 arrow가 있는 곳에서 시작해서 출력을 하기 때문에 StringBuilder에다가 화살표 있는 곳부터 시작해서 입력했다

원래는 원형 구조라서 어디서 시작하던 같은 값이 나와야하는데 출발점이 다르면 값이 다르기 때문에..

런타임에러가 난 이유는 조금 더 살펴보아야할 듯 합니다

혹시 수정 사항이 있다면 댓글 달아주세요!

0개의 댓글