Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

시간이 NullNull

[JAVA] [SWEA] 7584. 자가 복제 문자열 본문

알고리즘

[JAVA] [SWEA] 7584. 자가 복제 문자열

4NIng 2019. 6. 4. 21:14

문자열 P는 스스로를 계속 복제해서 매우 긴 문자열이 되었다.

복제하는 방법은 다음과 같다.

P0 = “0”

Pi+1 = Pi + “0” + f(g(Pi))

여기서, f(A) 함수는 문자열 A의 모든 문자를 반전시킨다.

예를 들어서, f(“10110”) = “01001”이다.

g(A)함수는 문자열 A를 좌우 반전 시킨다. 예를 들어서, g(“10110”) = “01101” 이다.

위와 같은 복제 방법을 무한히 반복한 문자열 P의 K번째 문자가 무엇인지 구하여라.

 

P1 = “001”

P2­ = “0010011”

P3 = “001001100011011”

위와 같이 복제가 이루어질 것이다.

따라서 3번째 문자는 1, 7번째 문자는 1, 10번째 문자는 0이다.

 

이 문제는 문자들의 규칙을 보고 점화식만 세워서 바로 추정하면 풀리는 문제인데

 

나도 처음에는 도대체 규칙이 무엇인지 한참을 쳐다보다가 알게 되었다.

 

인덱스를 문제처럼 맨 처음의 숫자를 첫번째로 하는 것이 아니라 0 번째라고 하였을때

 

1. 4의 배수의 숫자는 0 이다. f( 4n ) = 0

2. 4의 배수가 아닌 짝수는 1 이다. f( 4n + 2 ) = 1

3. 홀수의 경우 f( 2n + 1 ) = f( n )

 

이 규칙을 통해서 간단하게 코드를 짤 수가 있다.

 

1. 먼저 홀수 짝수를 나누고

2. 홀수 일 경우 1을 빼고 2를 나누어 준다.

3. 이 수가 4로 나누어 나머지가 0인지 확인한다.

4. 아니라면 2로 나누어 나머지가 0인지 확인한다.

5. 2~4 번을 반복하여 몇번째 숫자가 무엇인지 확인한다.

 

이때 0일 경우 0, 1일 경우 0 이기 때문에 초기 result 값은 0으로 해준다.

 

코드로 나타내면 다음과 같다.

 

이 문제의 경우 입력받는 k의 수가 10^18 까지 이기때문에 long으로 처리하였다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class D3Solution7584 {

	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		int T = Integer.parseInt(br.readLine());
		long k = 0;
		int result = 0;
		for(int t=1; t<=T; t++) {
			k = Long.parseLong(br.readLine())-1;
			result = 0;
			while(k > 0) {
				if(k%2 == 1) k = (k-1)/2;
				if(k%4 == 0) {result = 0; break;}
				else if(k%2 == 0) {result = 1; break;}
			}
			bw.write("#"+t+" "+result+"\n");
		}
		br.close();
		bw.close();
	}

}

 

Comments