{ }codelper
문자 하나P0226

좌석 코드로 표 번호 찾기

작은 극장의 좌석은 줄마다 w자리씩 있다. 1층 줄은 앞에서부터 A, B, …, Z이고, 그 뒤 2층 줄이 앞에서부터 a, b, …, z다. 좌석 코드는 줄 글자 하나와 그 줄의 자리 번호(1~w의 숫자 하나)를 이어 쓴 것이다.
예를 들어 B3은 1층 B줄의 3번 자리다. 표 번호는 A1이 1번, A2가 2번이고, 한 줄이 끝나면 다음 줄의 1번 자리로 이어진다.
Z줄 다음은 a줄이다. 즉 줄 글자가 맨 앞에서 r번째 줄(A가 0번째, Z가 25번째, a가 26번째, z가 51번째)이고 자리 번호가 s이면 표 번호는 r × w + s다. 첫 줄에 w와 좌석 코드 수 n이 빈칸 하나로 띄워 주어지고, 다음 n줄에 좌석 코드가 하나씩 주어진다. 좌석 코드마다 표 번호를 한 줄에 하나씩 출력하라.

입력
1 ≤ w ≤ 9, 1 ≤ n ≤ 100.
좌석 코드는 두 글자이고, 첫 글자는 영어 대문자(A~Z)나 소문자(a~z), 둘째 글자는 1 이상 w 이하의 숫자다
출력
n줄, 줄마다 표 번호(정수)
예시 1 · stdin
4 4
A1
B3
a2
Z4
stdout
1
7
106
104
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

글자 하나를 수로 바꾸는 방법이 언어마다 달라요.
C·C++·Java·C#의 char는 글자 코드를 담은 정수라서 row - 'A'가 바로 줄 차례이고 seat - '0'이 자리 번호예요.
그런데 - '0'을 빼먹고 seat를 그대로 계산에 쓰면 오류 없이 글자 코드가 들어가요('3'은 51).
Python·JS·TS·크레이콘에는 글자 타입이 없고 한 글자짜리 문자열뿐이라 코드를 꺼내야 해요: Python ord(c), JS·TS c.charCodeAt(0), 크레이콘 글자.코드(c).
Python ord("3")도 3이 아니라 51이에요(숫자 하나는 int("3")로도 돼요).
JS에서는 code[1]이 문자열 "3"이라 r * w + code[1]이 덧셈이 아니라 이어 붙이기가 되어 "43" 같은 답이 나와요.
크레이콘에서도 수 + 문자열은 이어 붙이기라서 r * w + code[1]이 "43"이 되니, 글자.코드로 수를 만든 다음 계산해요.
두 번째 함정은 2층이에요.
글자 코드에서 Z(90)와 a(97) 사이에는 다른 글자 6개가 있어서, 모든 줄 글자에서 'A'를 빼면 a가 26이 아니라 32째 줄이 돼요.
대문자인지 먼저 가리고('A' <= row <= 'Z', Java Character.isUpperCase, C# char.IsUpper) 소문자는 26 + (row - 'a')로 세요.
줄을 0부터 세는 것도 잊지 말아요.
A를 1째 줄로 세면 A1이 w + 1이 돼요.

Pythonmain.py · 11 줄
w, n = map(int, input().split())for _ in range(n):    code = input().strip()    row, seat = code[0], code[1]    # 글자는 ord로 코드를 얻어 뺀다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄    if "A" <= row <= "Z":        r = ord(row) - ord("A")    else:        r = 26 + ord(row) - ord("a")    s = ord(seat) - ord("0")        # int(seat)와 같다. ord(seat)만 쓰면 49~57이다    print(r * w + s)
JavaScriptmain.js · 14 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [w, n] = lines[0].trim().split(/\s+/).map(Number);const A = "A".charCodeAt(0), Z = "Z".charCodeAt(0), a = "a".charCodeAt(0), ZERO = "0".charCodeAt(0);const out = [];for (let i = 1; i <= n; i++) {  const code = lines[i].trim();  const row = code.charCodeAt(0);  // 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄  const r = row <= Z ? row - A : 26 + row - a;  // code[1]은 문자열 "7"이다. 수에 + 하면 이어 붙여지니 코드로 바꿔 뺀다  const s = code.charCodeAt(1) - ZERO;  out.push(r * w + s);}console.log(out.join("\n"));
TypeScriptmain.ts · 12 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [w, n]: number[] = lines[0].trim().split(/\s+/).map(Number);const out: number[] = [];for (let i = 1; i <= n; i++) {  const code: string = lines[i].trim();  const row: number = code.charCodeAt(0);  const r: number = row <= "Z".charCodeAt(0) ? row - "A".charCodeAt(0) : 26 + row - "a".charCodeAt(0);  const s: number = code.charCodeAt(1) - "0".charCodeAt(0);  out.push(r * w + s);}console.log(out.join("\n"));
JavaMain.java · 23 줄
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.StringTokenizer; public class Main {    public static void main(String[] args) throws Exception {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        StringTokenizer st = new StringTokenizer(br.readLine());        int w = Integer.parseInt(st.nextToken());        int n = Integer.parseInt(st.nextToken());        StringBuilder out = new StringBuilder();        for (int i = 0; i < n; i++) {            String code = br.readLine().trim();            char row = code.charAt(0);            char seat = code.charAt(1);            // char끼리 빼면 int다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄            int r = Character.isUpperCase(row) ? row - 'A' : 26 + (row - 'a');            int s = seat - '0'; // seat를 그대로 계산에 쓰면 글자 코드(49~57)가 들어간다            out.append(r * w + s).append('\n');        }        System.out.print(out);    }}
C#Main.cs · 24 줄
using System;using System.Text; class Program{    static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int w = int.Parse(first[0]);        int n = int.Parse(first[1]);        var sb = new StringBuilder();        for (int i = 0; i < n; i++)        {            string code = Console.ReadLine().Trim();            char row = code[0];            char seat = code[1];            // char끼리 빼면 int다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄            int r = char.IsUpper(row) ? row - 'A' : 26 + (row - 'a');            int s = seat - '0'; // char.GetNumericValue(seat)도 되지만 double을 돌려준다            sb.Append(r * w + s).Append('\n');        }        Console.Write(sb);    }}
C++main.cpp · 17 줄
#include <iostream>#include <string> int main() {    std::ios::sync_with_stdio(false);    int w, n;    std::cin >> w >> n;    for (int i = 0; i < n; i++) {        std::string code;        std::cin >> code;        char row = code[0], seat = code[1];        // 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄        int r = (row >= 'A' && row <= 'Z') ? row - 'A' : 26 + (row - 'a');        int s = seat - '0';        std::cout << r * w + s << '\n';    }}
Cmain.c · 16 줄
#include <stdio.h> int main(void) {    int w, n;    scanf("%d %d", &w, &n);    for (int i = 0; i < n; i++) {        char code[8];        scanf("%7s", code);        char row = code[0], seat = code[1];        /* char는 작은 정수라 바로 뺄 수 있다. 1층 A~Z는 0~25째 줄, 2층 a~z는 26~51째 줄 */        int r = (row >= 'A' && row <= 'Z') ? row - 'A' : 26 + (row - 'a');        int s = seat - '0'; /* seat만 쓰면 '7'의 코드 55가 들어간다 */        printf("%d\n", r * w + s);    }    return 0;}
Craykonmain.cray · 21 줄
first = 콘솔.줄읽기().공백제거().나누기(" ");w = first[0].수로변환();n = first[1].수로변환();반복 (i = 0; i < n; i++){    code = 콘솔.줄읽기().공백제거();    // 크레이콘에는 글자 타입이 없다. 한 글자 문자열을 글자.코드로 수로 바꿔 뺀다    row = 글자.코드(code[0]);    seat = 글자.코드(code[1]);    r = 0;    만약 (row <= 글자.코드("Z"))    {        r = row - 글자.코드("A");    }    아니면    {        r = 26 + row - 글자.코드("a");    }    s = seat - 글자.코드("0");    콘솔.쓰기(r * w + s);}