728x90
개요
문제 링크
골드 1, DP
매 단계 X->YZ, Y->Z, Z->X로 변형이 일어날 때 전체 길이 / 문자 개수 / k번째 문자 구하기
접근
규칙성을 찾으면 크게 어렵지 않다. 우선 X,Y,Z의 개수를 생각해보자. X는 Z에서 온다. Y는 X에서 온다. Z는 X,Y에서 온다. 온다는게 뭔 말이냐 하니, 변화의 이전단계를 생각해보자. 변화를 역으로 취해보면 알 수 있다. 따라서
X[i] = Z[i-1], Y[i] = X[i-1], Z[i] = X[i-1]+Y[i-1]
이게 성립한다. 문자열의 길이는 X[i]+Y[i]+Z[i]이니까 따로 생각할 필요는 없다.
어려운 부분은 K번째 문자 구하기이다. 문제를 잘 들여다보면 s[n]+s[n+1] = s[n+3]임을 알 수 있다. 왜냐? X는 세 번의 시행 뒤 XYZ가 된다. Y는 세 번의 시행 뒤 YZ가 된다. Z는 ZX가 된다.
// 현재+시행 X -> X+YZ, Y -> Y+Z, Z -> Z+X // 3번 시행 X -> XYZ, Y -> YZ, Z -> ZX
3번 시행한 결과와, 현재값 + 1번 시행한 결과가 같기 때문이다. 이걸 바탕으로 K번째 문자를 쉽게 구해줄 수 있다.
만약 k가 len[n-3] = n-3번째 문자열의 길이보다 크다면, 우리는 n-2번째 문자열의 k-len[n-3] 번째 문자를 구해야 한다. 그렇지 않다면 n-3번째 문자열의 k번째 문자를 구해주면 된다. 이게 뭔 말이냐,
// n = 6 // s[n] = ZXXYZ len[4] = 3, len[3] = 2 // XYZ, ZX // 1) k=3 // ZXXYZ // __O__ 이 위치 -> s[4]의 1번 위치 answer = s[4][1] = s[n-2][k-len[n-3]] // 2) k=2 // ZXXYZ // _O___ s[3]의 2번 위치 answer = s[3][2] = s[n-3][k]
그래서 n이 3보다 큰 동안 위 작업을 계속 반복해주면 된다. 그 뒤에는 직접 문자열을 구해 문자를 찾아주면 된다.
Pseudo code
// 개수
x[1] = 1, y[1] = 0, z[1] = 0
for (i = 2~n)
{x,y,z} = {z,x,x+y}
if (q==1) return x[n]+y[n]+z[n]
if (q==3) return input[n]
if (q==2)
while (3 < n)
if (len[n-3] < k)
n -= 2, k -= len[n-3]
else
n -= 3
// s[n] = s[n-2]+s[n-3]
s = "Y", t = "Z", u = "X"
while (--n)
{s,t,u} = {t,u,s+t}
return u[k-1]
Source code
#include <iostream>
using namespace std;
using ld = long long;
int main() {
ld q, n, k;
char a;
cin >> q >> n;
if (q==2) cin >> k;
if (q==3) cin >> a;
ld x[n+1],y[n+1],z[n+1];
x[1]=1,y[1]=0,z[1]=0;
for (int i=2; i<=n; i++)
x[i]=z[i-1],y[i]=x[i-1],z[i]=x[i-1]+y[i-1];
if (q==1) cout << x[n]+y[n]+z[n];
if (q==3) cout << (a=='X'?x:a=='Y'?y:z)[n];
if (q==2) {
while (3<n) {
ld n2=x[n-3]+y[n-3]+z[n-3];
if (k<=n2) n-=3;
else
n-=2, k-=n2;
}
string s,t,u,v;
s="Y",t="Z",u="X";
while(--n)
v=u,u=s+t,s=t,t=v;
cout << u[k-1];
}
}
728x90
'백준브실골 > DP' 카테고리의 다른 글
백준 13707, 합분해 2 (0) | 2023.02.17 |
---|---|
백준 5569, 출근 경로 (0) | 2023.02.17 |
백준 22968, 균형 (2) | 2023.02.17 |
백준 17856, Just Passing Through (0) | 2023.02.17 |
백준 13910, 개업 (0) | 2023.02.17 |
백준 5549, 행성 탐사 (0) | 2023.02.17 |
백준 14238, 출근 기록 (2) | 2023.02.12 |
백준 27210, 신을 모시는 사당 (0) | 2023.02.12 |
댓글