https://www.acmicpc.net/problem/2037
문제
> 핸드폰 자판을 이용해 영어메세지를 치려고 할때, 걸리는 최소시간을 구해라.
> 1번을 누르면 공백이 찍히고 ABC는 같은 번호에 있으므로 1번 누르면 A, 2번 누르면 B, 3번 누르면 C다.
> 같은번호에 있는 문자를 여러개 치기 위해선 일정시간을 기다려야 한다. 공백은 기다릴 필요없다.
> 입력 p,w에서 p는 버튼을 한번 누르는데 걸리는 시간, w는 같은문자를 연속으로 치기위해 걸리는 시간이다.
접근
특정 번호에 있는 알파벳에대해 map으로 정리한다.
입력받은 문자열을 하나씩 읽어가며 앞서 입력받은 문자열과 같은 value값을 가지는지 확인하고 그렇다면 w시간만큼 기다림, 버튼 누른횟수만큼 p값 누적하며 시간을 구한다.
문제해결
> 특정 번호에 있는 알파벳에 대해 map으로 정리하고 해당 알파벳을 누르는 횟수를 map으로 정리한다.
> 문자열을 한글자씩 읽어가며 앞서 입력받은 문자열과 비교한다. 공백이라면 그냥 누른 시간p를 추가하고 넘어가고 아닐때 번호가 같은 문자면 w시간만큼 기다린다. 이 시간을 누적한다.
> 누적된 시간을 출력한다.
코드
#include <iostream>
#include <algorithm>
#include <string>
#include <map>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int p, w;
cin >> p >> w;
cin.ignore();
string str;
getline(cin, str);
map<char, int> num = {
{'A', 2}, {'B', 2}, {'C', 2},
{'D', 3}, {'E', 3}, {'F', 3},
{'G', 4}, {'H', 4}, {'I', 4},
{'J', 5}, {'K', 5}, {'L', 5},
{'M', 6}, {'N', 6}, {'O', 6},
{'P', 7}, {'Q', 7}, {'R', 7}, {'S', 7},
{'T', 8}, {'U', 8}, {'V', 8},
{'W', 9}, {'X', 9}, {'Y', 9}, {'Z', 9},
{' ', 1}
};
map<char, int> times = {
{'A', 1}, {'B', 2}, {'C', 3},
{'D', 1}, {'E', 2}, {'F', 3},
{'G', 1}, {'H', 2}, {'I', 3},
{'J', 1}, {'K', 2}, {'L', 3},
{'M', 1}, {'N', 2}, {'O', 3},
{'P', 1}, {'Q', 2}, {'R', 3}, {'S', 4},
{'T', 1}, {'U', 2}, {'V', 3},
{'W', 1}, {'X', 2}, {'Y', 3}, {'Z', 4},
{' ', 1}
};
int t_time = 0;
for (int i = 0; i < str.length(); i++)
{
if (i > 0 && num[str[i]] == num[str[i - 1]] && num[str[i]] != 1)
{
t_time += w;
}
t_time += times[str[i]] * p;
}
cout << t_time;
}

후기
이차원 map을 써봤지만 value에 접근하는게 좀 꼬여 두개의 map으로 분할했다. map을 직접입력하는게 별로 맘에 들지않아 줄일 수 있는 방법을 알아보자.