{ }codelper
字符P0226

由座位编码求票号

小剧场的座位每排有 w 个。
一楼的排从前往后是 A, B, …, Z,其后是二楼的排,从前往后是 a, b, …, z。
座位编码是一个排字母后面接上该排的座位号(1~w 的一位数字)。
例如 B3 是一楼 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()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

把一个字符变成数字的方法因语言而异。
C、C++、Java、C# 的 char 是存着字符编码的整数,所以 row - 'A' 直接就是排的序号,seat - '0' 就是座位号。
但如果忘了 - '0',直接把 seat 拿去计算,字符编码会不报错地混进去('3' 是 51)。
Python、JS、TS、Craykon 没有字符类型,只有单字符字符串,所以要取出编码:Python ord(c),JS/TS c.charCodeAt(0),Craykon 字符.编码(c)。
Python 的 ord("3") 也是 51 而不是 3(一位数字也可以用 int("3"))。
在 JS 里 code[1] 是字符串 "3",r * w + code[1] 不是加法而是拼接,得到 "43" 这样的答案。
在 Craykon 里,数字 + 字符串同样是拼接,r * w + code[1] 会得到 "43",所以要先用 字符.编码 变成数字再计算。
第二个陷阱是二楼。
字符编码中 Z(90)和 a(97)之间还有 6 个别的字符,所以对所有排字母都减 'A',a 就成了第 32 排而不是第 26 排。
要先判断是不是大写('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);}