문제
a : b = c : d의 비율 관계를 알파벳 오프셋에 적용하여 미지의 단어 d를 구한다. 각 위치 i에서 b[i]가 a[i]에 대해 가지는 알파벳 오프셋 차이를 c[i]에 더해 d[i]를 계산한다. 결과는 26개 알파벳 범위 내에서 순환한다.
입력은 #이 나올 때까지 계속된다.
입력
- 각 줄: a b c (같은 길이의 소문자 알파벳 문자열 세 개)
- 마지막 줄:
#
출력
각 테스트 케이스마다 a, b, c, d를 공백으로 구분하여 한 줄에 출력한다.
예제
| 입력 | 출력 |
|---|---|
dog cat fog # | dog cat fog ___ (d = fog의 각 문자에 cat-dog 오프셋 적용) |
풀이
a : b = c : d에서 각 위치 i에 대해 d[i]를 계산하는 문자열 수학 문제다. 알파벳을 0~25의 정수로 취급하고 26으로 나머지 연산을 적용한다.
- 단어 a를 읽는다.
"#"이면 종료한다. - 단어 b, c를 읽는다.
- 단어 a의 길이 n을 기준으로 각 위치 i를 순회한다.
x = (c[i] - 'a') + (b[i] - 'a') - (a[i] - 'a')를 계산한다.(x + 26) % 26으로 음수를 방지하며 0~25 범위로 정규화한다.- 결과에
'a'를 더해 문자로 변환하고 d를 완성한다. a b c d를 한 줄에 출력한다.
핵심 아이디어: a : b = c : d를 알파벳 오프셋 덧셈으로 해석한다. d[i] = c[i] + (b[i] - a[i]) (mod 26). b에서 a를 뺀 오프셋이 음수가 될 수 있으므로 +26을 더한 뒤 26으로 나머지 연산을 적용해 항상 양수 범위로 유지한다.
코드
#include <iostream>
#include <string>
using namespace std;
int main(void) {
cin.tie(0);
ios::sync_with_stdio(0);
while (1) {
string a, b, c; cin >> a; if (a == "#") break; cin >> b >> c;
int n = a.size();
cout << a << ' ' << b << ' ' << c << ' ';
for (int i = 0; i < n; i++) {
int x = (c[i] - 'a');
x = (x + (b[i] - 'a') - (a[i] - 'a') + 26) % 26;
cout << (char)(x + 'a');
}
cout << '\n';
}
return 0;
}복잡도
- 시간: O(T * N) — 테스트 케이스 수 T, 단어 길이 N에 대해 각 위치를 한 번씩 순회
- 공간: O(N) — 세 단어 문자열 저장