CC BY 4.0 (except where otherwise noted or for reposted articles)
문제
A와 B가 주어지면 A+B를 구해야 한다. 다만 이 문제는 투 스텝 문제이다. 즉 프로그램이 두번 실행되는데 첫 번째 실행에는 길이가 13인 문자열을 출력해야 하고 이 문자열이 두 번째 실행의 입력으로 주어질 때 두 번째 실행에 A+B의 값을 구해야 한다.
풀이
풀이 자체는 알고 보면 단순하지만 떠올리기 직관적이지 않을 수는 있다. 길이가 13이라는 점, 그리고 소문자 알파멧으로만 구성된 문자열을 만들 수 있음에 주목해보자. 뭔가 굉장히 인위적인 설정 같지 않은가?
문자열에서 수를 찾는다니 뭔가 16진수가 생각이 난다 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F). 이걸 처음부터 알파벳만 써서 A, B, … , O, P로 표현하면 안될까? 아쉽게도 $16^{13} - 1$ 은 $4.5 \times 10^{15}$ 언저리라 부족하다.
음? 하지만 이렇게 할거라면 26가지 문자를 전부 써서 26진법을 만든다면 어떨까? 마침 $26^{13} - 1$ 은 $2 \times 10^{18}$보다 커서 A+B의 답으로 가능한 수 범위를 전부 표현 가능하다.
그렇다면 첫 번째 실행에는 A+B를 계산한 결과를 26진수로 변환, 두 번째 실행에는 입력받은 26진수를 10진수로 변환하면 끝날것임을 알 수 있다! 바로 짜보도록 하자.
코드 (C++)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void s1(){
ll A, B; cin >> A >> B;
A += B;
string ret="";
for(int i=0; i<13; i++){
ret += 'a' + A % 26;
A /= 26;
} cout << ret;
}
void s2(){
string ret; cin >> ret;
ll res = 0; ll p26 = 1;
for(int i=0; i<13; i++){
res += (ret[i]-'a')*p26;
p26 *= 26;
}
cout << res;
}
int main(){
int T; cin >> T;
if(T==1) s1();
else s2();
}
폰 코딩으로 풀어서 평소에 쓰는 템플릿 없이 굉장히 깔끔하다.