본문 바로가기

문제 풀이/문제 풀이(BOJ)

[Silver V] 이름 궁합 테스트 - 17269

[문제 위치]

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

[문제 풀이]

이 문제는 구현 알고리즘을 통해 해결하는 문제이다.
두 사람의 이름을 번갈아가며 합친 문자열을 만들고, 각 문자를 문제에서 주어진 알파벳 획수 표(A~Z → 3 2 1 2 4 3 1 3 1 1 3 1 3 2 1 2 2 2 1 2 1 1 1 2 2 1)에 맞춰 숫자로 변환한다'
그 다음 인접한 두 수의 합을 10으로 나눈 값으로 한 줄씩 줄여 나가는 과정을 길이가 2가 될 때까지 반복하면 두 자리 수가 남고, 이를 확률(%)로 출력한다. 단, 십의 자리가 0이면 일의 자리만 출력하므로 정수값으로 출력하면 자연스럽게 처리된다.


아래는 이를 구현한 코드이다.

#include <iostream>
#include <vector>
#include <string>
using namespace std;

#define FASTIO ios::sync_with_stdio(false); cin.tie(nullptr);

int main() {
    FASTIO;

    int n, m;
    cin >> n >> m;
    string A, B;
    cin >> A >> B;

    // 알파벳별 획수 매핑 (A~Z)
    int val[26] = {
        3,2,1,2,4,3,1,3,1,1,3,1,3,2,1,2,2,2,1,2,1,1,1,2,2,1
    };

    // 이름을 교차로 이어 붙이고 남은 글자는 뒤에 붙인다
    string mix;
    mix.reserve(n + m);
    int k = min(n, m);
    for (int i = 0; i < k; ++i) {
        mix += A[i];
        mix += B[i];
    }
    if (n > k) mix += A.substr(k);
    if (m > k) mix += B.substr(k);

    // 숫자열로 변환
    vector<int> arr;
    arr.reserve(n + m);
    for (char c : mix) arr.push_back(val[c - 'A']);

    // 인접 합(모듈로 10)으로 길이 2가 될 때까지 줄이기
    while (arr.size() > 2) {
        vector<int> nxt;
        nxt.reserve(arr.size() - 1);
        for (size_t i = 0; i + 1 < arr.size(); ++i) {
            nxt.push_back((arr[i] + arr[i + 1]) % 10);
        }
        arr.swap(nxt);
    }

    int percent = arr[0] * 10 + arr[1]; // 정수 값으로 출력하면 05% -> 5% 자동 처리
    cout << percent << "%\n";
    return 0;
}