문제
엑셀의 첫 번째 열은 A이고, 두 번째 열은 B이고, 26번째 열은 Z이다. 26번째 열 다음 열부터는 2글자를 이용한다.
예를 들어, 27번째 열은 AA이고, 28번째 열은 AB, 52번째 열은 AZ이다. 그 다음 53번째 열은 BA이며, 이와 같이 계속 열의 이름을 붙인다.
ZZ열 다음 열은 AAA가 되고, 그 다음은 AAB가 된다.
엑셀에서 행은 그냥 행 번호를 사용하면 된다.
엑셀 스프레드시트에서 각 칸은 위에서 설명한 열과 행을 합쳐서 이름을 만들 수 있다.
가장 왼쪽 위에 있는 칸은 A1이 되고, 55열 23행에 있는 칸은 BC23이 된다.
열과 행이 주어졌을 때, 그 칸의 엑셀 스프레드시트 상에서 이름을 출력하는 프로그램을 작성하시오.
입력
입력은 여러 줄이며, RnCm형태이다. n은 행 번호 (1<=n<=300000000), m은 열 번호 (1<=m<=300000000) 이다.
입력의 마지막은 n과 m이 모두 0이며, 이때는 출력하지 않고 프로그램을 종료하면 된다.
출력
각 입력을 순서대로 한 줄에 하나씩 엑셀 스프레드시트 상에서의 이름을 출력하면 된다.
알고리즘
수학
문자열
해결 방법
간단하게 말하면 열을 26진수
로 변환하여 출력하면 된다.
이 아이디어가 바로 떠오르지 않아서 구글링의 도움을 받았다.
이외에도 주의해야 할 점이 몇개 있는데.
먼저 입력형식이 R숫자C숫자
형식의 문자열이다 보니 파싱
이 필요하다.
처음에는 c++에서 string으로 입력받고 strlen
으로 행과 열을 뽑아내려고 했는데
그럼 C의 위치로 알아야 하고... strlen도 2번 적용해야되고... 이렇게 뽑아낸 문자열을 또 정수로 변환까지 해줘야 한다.
그냥 scanf
를 사용하면 한 줄로 끝낼 수 있다^_^
for(int i = 0; m > 0; i++) {
m--; // 'A'에 나머지를 더해줄 것이기 때문에 시작 인덱스를 하나 줄여야 함
colNum[i] = ('A' + m%26);
m /= 26;
}
이 부분이 26진수로 변환하는 메인 로직인데
m--
을 해주는 이유는 colNum[i] 에 문자를 삽입할 때 숫자에 'A'를 더한 뒤에 저장할 것이기 때문이다.
예를 들어, 52라는 열 번호를 26진수로 나타내려면
51 % 26 = 25 -> 'A' + 25 = 'Z'가 되는 것이다.
만약 m-- 과정이 없다면 10진수 52는 26진수로 20이라는 이상한 값이 나오게 된다.
낮은 차수부터 먼저 값이 저장되기 때문에 마지막에 출력할때는 뒤집어서
출력하면 된다.
만약 input을 string으로 받고 여기서 reverse
함수를 사용하면 시간초과가 나니 이 방법은 사용하지 말 것,,
내 코드(C++)
// [2757] 엑셀
// 구현, 수학, 문자열
#include <cstdio>
#include <cstring>
using namespace std;
int main(void)
{
int n, m;
while(true) {
char colNum[10] = {'0', };
scanf("R%dC%d", &n, &m);
if(n == 0 && m == 0) {
break;
}
for(int i = 0; m > 0; i++) {
m--; // 'A'에 나머지를 더해줄 것이기 때문에 시작 인덱스를 하나 줄여야 함
colNum[i] = ('A' + m%26);
m /= 26;
}
for(int i = strlen(colNum) - 1; i >= 0; i--) {
printf("%c", colNum[i]);
}
printf("%d\n", n);
getchar(); // '\n' 제거
}
return 0;
}
'Baekjoon > 문자열' 카테고리의 다른 글
[20291] 파일 정리 (0) | 2022.06.21 |
---|---|
[17413] 단어 뒤집기2 (0) | 2022.06.21 |
[1157] 단어 공부 (0) | 2020.06.27 |
[11720] 숫자의 합(C / C++) (0) | 2020.06.27 |
[8958] OX퀴즈 (0) | 2020.06.22 |