공부/백준

백준 17269번: 이름궁합 테스트(C++)

상연 2020. 12. 7. 13:24

목차

    www.acmicpc.net/problem/17269

     

    17269번: 이름궁합 테스트

    시윤이는 좋아하는 이성이 생기면 가장 먼저 이름궁합부터 본다. 이름궁합을 보는 방법은 간단하다. 먼저 이름을 알파벳 대문자로 적는다. 각 알파벳 대문자에는 다음과 같이 알파벳을 적는데

    www.acmicpc.net

    코드

    #include <iostream>
    #include <vector>
    using namespace std;
    
    int alp[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};
    int len1, len2;
    string name1, name2;
    vector <int> v;
    
    void init(){
    	cin >> len1 >> len2;
    	cin >> name1 >> name2;
    	int max_len = len1 > len2 ? len1 : len2;
    	for(int i=0; i<max_len; i++){
    		if(len1 > i) v.push_back(alp[int(name1[i])-65]);
    		if(len2 > i) v.push_back(alp[int(name2[i])-65]);
    	}
    }
    
    void test(vector<int> v){
    	if(v.size() == 2){
    		int score = 10 * v[0] + v[1];
    		cout << score << "%";
    		return;}
    	vector <int> v2;
    	for(int i=1; i<v.size(); i++){
    		v2.push_back((v[i] + v[i-1])%10);
    	}
    	test(v2);
    }
    int main() {
    	init();
    	test(v);
    }

    풀이

    다들 학교 다니면서 한 번쯤은 해 봤을수도 있고, 드라마로 하는 걸 본 적이 있는 테스트입니다.

    이름의 글자 획수로 궁합이 맞나 안 맞나 테스트 해 보는 건데요.

    입출력을 받고 그걸 정리하는게 좀 귀찮은 거지 로직 자체는 어렵지 않은 문제입니다.

    void init(){
    	cin >> len1 >> len2;
    	cin >> name1 >> name2;
    	int max_len = len1 > len2 ? len1 : len2;
    	for(int i=0; i<max_len; i++){
    		if(len1 > i) v.push_back(alp[int(name1[i])-65]);
    		if(len2 > i) v.push_back(alp[int(name2[i])-65]);
    	}
    }

    이 부분이 입력을 받는 부분입니다.

    우선 두 이름의 길이 중 긴 길이의 값을 따로 빼냅니다.

    그 다음 배열의 index 0 ~ (긴 길이- 1)까지 반복문을 해 주면서

    Vector v에 입력받은 이름 순서대로 각 index 글자의 획수를 벡터에 추가해줍니다.

    추가하다 보면 어느순간 더 짧은 이름은 이미 다 추가가 되었고 나머지 긴 글자의 글자가 남은 상황이 되는데요

    나머지 이름의 각 글자횟수를 v에 추가 해 줍니다.

    아스키코드상 'A'는 65의 decimal 값을 가지게 됩니다. 따라서 int('대문자 알파벳') - 65를 하면 0부터 시작해서 그 알파벳이 몇번째인지 알 수 있으며, 이를 통해 우리는 그 글자의 획수를 바로 알 수 있습니다.


    이제 입력을 받았으니 궁합을 봐 볼까요?

    저 같은경우에는 재귀함수로 작성을 했습니다.

    void test(vector<int> v){
    	if(v.size() == 2){
    		int score = 10 * v[0] + v[1];
    		cout << score << "%";
    		return;}
    	vector <int> v2;
    	for(int i=1; i<v.size(); i++){
    		v2.push_back((v[i] + v[i-1])%10);
    	}
    	test(v2);
    }

    수행을 할 때마다 Vector v의 길이는 1씩 줄어들게 됩니다.

    왜냐하면 

    1 3 5 7 이렇게 길이가 4인 Vector가 초기상태로 주어질 시,

    v[0] + v[1]  / v[1] + v[2] / v[2] + v[3] 

    이렇게 더해져서 길이가 3인 Vector가 되기 때문입니다.

    주어진 Vector를 더해줘서 길이가 줄어든 새로운 Vector로 생성을 해 주고 다시 그 Vector를 인자로 넣어 재귀하면, 언젠가는 길이가 2인 Vector가 됩니다. 그때 그 Vector의 원소를 조합해서 출력 해 주면 정답이 됩니다.