영어 끝말잇기
문제 설명
1부터 n까지 번호가 붙어있는 n명의 사람이 영어 끝말잇기를 하고 있습니다. 영어 끝말잇기는 다음과 같은 규칙으로 진행됩니다.
1. 1번부터 번호 순서대로 한 사람씩 차례대로 단어를 말합니다.
2. 마지막 사람이 단어를 말한 다음에는 다시 1번부터 시작합니다.
3. 앞사람이 말한 단어의 마지막 문자로 시작하는 단어를 말해야 합니다.
4. 이전에 등장했던 단어는 사용할 수 없습니다.
5. 한 글자인 단어는 인정되지 않습니다.
다음은 3명이 끝말잇기를 하는 상황을 나타냅니다.
tank → kick → know → wheel → land → dream → mother → robot → tank
위 끝말잇기는 다음과 같이 진행됩니다.
- 1번 사람이 자신의 첫 번째 차례에 tank를 말합니다.
- 2번 사람이 자신의 첫 번째 차례에 kick을 말합니다.
- 3번 사람이 자신의 첫 번째 차례에 know를 말합니다.
- 1번 사람이 자신의 두 번째 차례에 wheel을 말합니다.
- (계속 진행)
끝말잇기를 계속 진행해 나가다 보면, 3번 사람이 자신의 세 번째 차례에 말한 tank 라는 단어는 이전에 등장했던 단어이므로 탈락하게 됩니다.
사람의 수 n과 사람들이 순서대로 말한 단어 words 가 매개변수로 주어질 때, 가장 먼저 탈락하는 사람의 번호와 그 사람이 자신의 몇 번째 차례에 탈락하는지를 구해서 return 하도록 solution 함수를 완성해주세요.
제한사항
- 끝말잇기에 참여하는 사람의 수 n은 2 이상 10 이하의 자연수입니다.
- words는 끝말잇기에 사용한 단어들이 순서대로 들어있는 배열이며, 길이는 n 이상 100 이하입니다.
- 단어의 길이는 2 이상 50 이하입니다.
- 모든 단어는 알파벳 소문자로만 이루어져 있습니다.
- 끝말잇기에 사용되는 단어의 뜻(의미)은 신경 쓰지 않으셔도 됩니다.
- 정답은 [ 번호, 차례 ] 형태로 return 해주세요.
- 만약 주어진 단어들로 탈락자가 생기지 않는다면, [0, 0]을 return 해주세요.
입출력 예
n | words | result |
3 | ["tank", "kick", "know", "wheel", "land", "dream", "mother", "robot", "tank"] | [3,3] |
5 | ["hello", "observe", "effect", "take", "either", "recognize", "encourage", "ensure", "establish", "hang", "gather", "refer", "reference", "estimate", "executive"] | [0,0] |
2 | ["hello", "one", "even", "never", "now", "world", "draw"] | [1,3] |
입출력 예 설명
입출력 예 #1
3명의 사람이 끝말잇기에 참여하고 있습니다.
- 1번 사람 : tank, wheel, mother
- 2번 사람 : kick, land, robot
- 3번 사람 : know, dream, tank
와 같은 순서로 말을 하게 되며, 3번 사람이 자신의 세 번째 차례에 말한 tank라는 단어가 1번 사람이 자신의 첫 번째 차례에 말한 tank와 같으므로 3번 사람이 자신의 세 번째 차례로 말을 할 때 처음 탈락자가 나오게 됩니다.
입출력 예 #2
5명의 사람이 끝말잇기에 참여하고 있습니다.
- 1번 사람 : hello, recognize, gather
- 2번 사람 : observe, encourage, refer
- 3번 사람 : effect, ensure, reference
- 4번 사람 : take, establish, estimate
- 5번 사람 : either, hang, executive
와 같은 순서로 말을 하게 되며, 이 경우는 주어진 단어로만으로는 탈락자가 발생하지 않습니다. 따라서 [0, 0]을 return하면 됩니다.
입출력 예 #3
2명의 사람이 끝말잇기에 참여하고 있습니다.
- 1번 사람 : hello, even, now, draw
- 2번 사람 : one, never, world
와 같은 순서로 말을 하게 되며, 1번 사람이 자신의 세 번째 차례에 'r'로 시작하는 단어 대신, n으로 시작하는 now를 말했기 때문에 이때 처음 탈락자가 나오게 됩니다.
시작 코드
#include <string>
#include <vector>
#include <iostream>
using namespace std;
vector<int> solution(int n, vector<string> words) {
vector<int> answer;
// [실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
cout << "Hello Cpp" << endl;
return answer;
}
나의 풀이
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> solution(int n, vector<string> words)
{
vector<string> v;
for (int i = 0; i < words.size(); i++)
{
if (i > 0 && words[i - 1].back() != words[i].front())
return { i % n + 1, i / n + 1 };
if (find(v.begin(), v.end(), words[i]) != v.end())
return { i % n + 1, i / n + 1 };
v.push_back(words[i]);
}
return { 0, 0 };
}
코드 분석
스트링 벡터 v를 만들고 for문에서 words를 돌리고 if문 두개를 작성합니다. 첫번째 if 문은 i가 0보다 크고 words의 i-1번째 인덱스의 마지막 값이 words의 i번째 인덱스의 첫번째 값과 다를 때라는 조건을 걸고, 조건이 성립한다면 i를 n+1로 나눈 나머지와 나눈 값을 리턴합니다.
다음 if문에서는 v의 처음부터 끝까지 words의 i번째 인덱스 값을 찾고 그 값이 v의 마지막 값과 다를 때 입니다. 이 조건이 성립하면 이전 if문과 같은 결과를 리턴합니다.
if문을 지난다음 v에 words[i]를 추가하고 for문을 빠져나옵니다. 마지막엔 0,0을 리턴하고 종료합니다.
풀이 설명
문제 설명을 보면 상당히 길고 복잡해 보이지만, 우리가 평소에 하는 끝말잇기의 규칙과 동일합니다. 단지 영어로 진행하며 마지막 영단어를 이어서 진행한다는 것이 다를 뿐입니다. 코드에서 구현해야 하는 것은 주어진 words와 인원수를 가지고 탈락조건에 해당하는 사람의 번호와 회차를 찾아내는 것입니다.
for문을 통해 words를 돌리면서 시작하고, 첫번째 if문은 복잡해 보이지만, 단순합니다. 끝말잇기의 첫번째 단어를 말하는 사람을 제외하고 두번째부터 끝말잇기의 조건을 체크하기 위한 것으로, 이전 단어의 마지막 글자와 이번 단어의 첫글자를 비교하여 같은지 확인하는 과정입니다. 리턴 값은 { 번호, 회차 }를 반환해야 하므로, 총 3명일 때, 첫 회차의 2번째 사람이라면, 1 % 3 + 1로 2가 나오고, 1 / 3 + 1로 1이 나와서 { 2, 1 }이라는 결과가 나옵니다. 아래 다른 if문도 동일한 리턴값을 갖도록 되어 있습니다.
두번째 if문은 v에서 words[i]와 같은 값을 찾는 것으로, 이전에 같은 단어를 말했는지 체크하는 과정입니다. 이 또한 탈락자를 찾는 과정으로, 탈락자의 번호와 회차를 반환하도록 되어 있습니다.
위 두 조건문에서 걸리지 않는다면, v에 해당 단어를 넣어줍니다. 첫번째는 무조건 v에 들어가게 됩니다. 그리고 모든 과정을 거쳐도 탈락자가 나오지 않을 경우, 제한사항에서 말했던 것처럼 { 0, 0 }을 리턴하도록 하고 종료합니다. 입출력 예 1번을 예제로 한 실행과정은 이미 문제설명에 나와 있으므로 생략하도록 하겠습니다.
<NEXT>
이번에는 정답률 70%의 Summer/Winter Coding(~2018) 문제인 "영어 끝말잇기"를 풀어보았습니다. 다음에는 탐욕법 카테고리에 속하는 "구명보트" 문제를 살펴보도록 하겠습니다. 감사합니다.
'프로그래머스 코딩테스트 문제 > Level 2' 카테고리의 다른 글
[프로그래머스] - 구명보트(C++) (0) | 2025.01.08 |
---|---|
[프로그래머스] - 점프와 순간이동(C++) (0) | 2024.12.13 |
[프로그래머스] - N개의 최소공배수(C++) (1) | 2024.12.08 |
[프로그래머스] - 카펫(C++) (2) | 2024.12.03 |
[프로그래머스] - 짝지어 제거하기(C++) (0) | 2024.11.27 |