[프로그래머스/C++] 조이스틱
1.문제 링크
2. 풀이 전 계획과 생각
- 구현
3. 풀이
#include <string>
using namespace std;
int solution(string name) {
int answer=0;
string initStr="";
// 위, 아래
for(int i=0;i<name.size();i++) initStr+="A";
for(int i=0;i<name.size();i++){
if(name[i]!=initStr[i]){
int source=65;
int dest=int(name[i]);
answer+=min(dest-source,90-dest+1);
}
}
// 오른쪽, 왼쪽
if(name[1]=='A'){
int cnt=0;
for(int i=1;i<name.size();i++){
if(name[i]=='A') cnt++;
else break;
}
answer+=(name.size()-1-cnt);
}
else{
if(name[name.size()-1]=='A'){
int cnt=0;
for(int i=name.size()-1; i>=1;i--){
if(name[i]=='A') cnt++;
else break;
}
answer+=(name.size()-1-cnt);
}
else{
int temp1 = (name.size()-1);
int start_index;
for(int i=1;i<name.size();i++){
if(name[i]=='A'){
start_index=i;
break;
}
}
int cnt=0;
for(int i=start_index;i<name.size();i++){
if(name[i]=='A') cnt++;
else break;
}
int temp2 = 2*(start_index-1) + (name.size()-cnt-start_index);
answer += min(temp1, temp2);
}
}
return answer;
}
크게 알파벳 변경과 커서 이동으로 나누어 구현한다.
알파벳 구현의 경우 목표로하는 아스키코드와 ‘A’ 아스키코드 65를 기준으로 dest - 65 와 90 - dest + 1 중 작은값이 정답이다. 전자의 경우 ‘A’에서 목표 문자까지 증가하는 것이고, 후자는 ‘A’에서 ‘Z’로 가서 목표 문자를 찾는 방법이다.
커서 이동의 경우 name[1]이 ‘A’인 경우와 아닌경우로 나눈다.
- ‘A’인 경우 연속된 ‘A’개수를 구한다. 커서를 왼쪽으로 이동하는 경우밖에 없어 전체 문자열 크기에서 연속된 ‘A’와 1을 빼준다.
- ‘A’가 아닌경우 2-1. 문자열 마지막이 ‘A’인 경우 마지막 ‘A’부터 그 앞까지 연속된 ‘A’개수를 구해 빼준다. 2-2. 문자열 마지막이 ‘A’가 아닌 경우 오른쪽으로 갔다 왼쪽으로 가는경우와 그냥 오른쪽으로 순회하는 방법 중 작은 값을 정답으로 더한다.
4. 풀이하면서 고민했던 점
- 최소로 가는 방법은 양방향 이동의 경우도 있다. 테스트 케이스 11에서 오류가 났다. 커뮤니티에 “ABAAAAAAAAABB” - 7 예외 사항이 있었다. 처음에는 무조건 한방향으로만 가는것이 최소 이동인줄 알았는데 위와 같은 케이스는 양방향으로 이동해야 최소 이동이 나온다.