{ }codelper
リストの添字P0224

一方向のバス路線でかかる時間

一方向にだけ走るバス路線に停留所が n 個ある。
一行目に n が与えられる。
二行目に停留所の名前 n 個が、バスが通る順に空白で区切って与えられる。
名前はすべて異なる。
三行目に、バスが出発点を出てから各停留所に着くまでの時間(分)n 個が同じ順に空白で区切って与えられる。
最初の値は 0 で、後ろほど大きくなる。
四行目に問いの数 q が与えられ、続く q 行に問いが "A B" の形で一つずつ与えられる。
問いごとに、停留所 A で乗って停留所 B で降りる。
進む停留所の数(B の順番から A の順番を引いた値)とかかる時間(分)を空白一つで区切って一行に出力せよ。
A か B が路線にないとき、または B が A より前にあるとき(バスは逆には走らない)は -1 を出力せよ。
A と B が路線上の同じ停留所なら "0 0" を出力する。
A と B が同じでも路線にない名前なら -1 である。

入力
1 ≤ n ≤ 1,000、名前は英小文字 1〜10 字、0 = 最初の時間 < … < 最後の時間 ≤ 100,000、1 ≤ q ≤ 1,000、問いの A・B も英小文字 1〜10 字(路線にないこともある)
出力
q 行、各行に「停留所数 時間」か -1
例 1 · stdin
5
city park school market river
0 4 9 15 22
5
park market
city river
market park
school school
park zoo
stdout
2 11
4 22
-1
0 0
-1
例 2 · stdin
2
a b
0 100000
3
a b
b a
zoo a
stdout
1 100000
-1
-1
main.py
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

名前から番号を探し(index-of)、その番号で別のリストの値を読む問題です。
探し方と見つからないときの結果は言語によって違います。
JS・TS stops.indexOf(a)、Java List.indexOf、C# Array.IndexOf、Craykon stops.位置検索(a) は見つからないと -1 を返します。
Python list.index は見つからないと ValueError を出すので、先に in で確かめます。
C++ std::find は見つからないと end() を返し、C の標準ライブラリには配列を順に調べて探す関数がないので(bsearch は並べ替え済みの配列用)、strcmp で回る関数を自分で書きます。
落とし穴は -1 を確かめずにそのまま番号として使うことです(Python なら自分で書いた探す関数や dict.get(a, -1) から -1 を受け取ったとき)。
Python では times[-1] がエラーなしに最後の停留所の時間になるので、もっともらしい間違った答えが出ます。
JS・TS の times[-1] は undefined なので NaN が出ます。
逆に、見つかったかを > 0 で聞くと、番号 0 の最初の停留所をないと言ってしまいます。
見つかったかは >= 0 か != -1 で聞きます。
Java で入力から読んだ文字列を == で比べると、中身が同じでも別のオブジェクトなので見つかりません。
indexOf は equals で比べるので大丈夫です。
逆向きの問いは絶対値で答えず -1 です。

Pythonmain.py · 17 行
n = int(input())stops = input().split()times = list(map(int, input().split()))q = int(input())out = []for _ in range(q):    a, b = input().split()    # list.index는 없으면 ValueError를 내니 먼저 in으로 확인한다    if a not in stops or b not in stops:        out.append("-1")        continue    i, j = stops.index(a), stops.index(b)    if j < i:                       # 버스는 거꾸로 가지 않는다        out.append("-1")    else:        out.append(f"{j - i} {times[j] - times[i]}")   # 같은 번호로 다른 목록을 읽는다print("\n".join(out))
JavaScriptmain.js · 16 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const stops = lines[1].trim().split(" ");const times = lines[2].trim().split(" ").map(Number);const q = Number(lines[3]);const out = [];for (let t = 0; t < q; t++) {  const [a, b] = lines[4 + t].trim().split(" ");  const i = stops.indexOf(a); // 없으면 -1  const j = stops.indexOf(b);  if (i === -1 || j === -1 || j < i) {    out.push("-1");  } else {    out.push(`${j - i} ${times[j] - times[i]}`);  }}console.log(out.join("\n"));
TypeScriptmain.ts · 17 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const stops: string[] = lines[1].trim().split(" ");const times: number[] = lines[2].trim().split(" ").map(Number);const q: number = Number(lines[3]);const out: string[] = [];for (let t = 0; t < q; t++) {  const [a, b] = lines[4 + t].trim().split(" ");  const i: number = stops.indexOf(a); // 없으면 -1  const j: number = stops.indexOf(b);  if (i === -1 || j === -1 || j < i) {    out.push("-1");  } else {    out.push(`${j - i} ${times[j] - times[i]}`);  }}console.log(out.join("\n"));
JavaMain.java · 25 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;import java.util.List; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        in.readLine();        List<String> stops = Arrays.asList(in.readLine().trim().split(" "));        int[] times = Arrays.stream(in.readLine().trim().split(" ")).mapToInt(Integer::parseInt).toArray();        int q = Integer.parseInt(in.readLine().trim());        StringBuilder out = new StringBuilder();        for (int t = 0; t < q; t++) {            String[] p = in.readLine().trim().split(" ");            int i = stops.indexOf(p[0]); // 없으면 -1(문자열 내용으로 비교한다)            int j = stops.indexOf(p[1]);            if (i == -1 || j == -1 || j < i) out.append("-1");            else out.append(j - i).append(' ').append(times[j] - times[i]);            out.append('\n');        }        System.out.print(out);    }}
C#Main.cs · 25 行
using System;using System.Linq;using System.Text; class Program{    static void Main()    {        Console.ReadLine();        string[] stops = Console.ReadLine().Trim().Split(' ');        int[] times = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray();        int q = int.Parse(Console.ReadLine());        var sb = new StringBuilder();        for (int t = 0; t < q; t++)        {            string[] p = Console.ReadLine().Trim().Split(' ');            int i = Array.IndexOf(stops, p[0]); // 없으면 -1, 첫 정류장은 0            int j = Array.IndexOf(stops, p[1]);            if (i < 0 || j < 0 || j < i) sb.Append("-1");            else sb.Append(j - i).Append(' ').Append(times[j] - times[i]);            sb.Append('\n');        }        Console.Write(sb);    }}
C++main.cpp · 28 行
#include <algorithm>#include <iostream>#include <string>#include <vector> int main() {    std::ios::sync_with_stdio(false);    int n, q;    std::cin >> n;    std::vector<std::string> stops(n);    std::vector<int> times(n);    for (auto& s : stops) std::cin >> s;    for (int& x : times) std::cin >> x;    std::cin >> q;    for (int t = 0; t < q; t++) {        std::string a, b;        std::cin >> a >> b;        // std::find는 못 찾으면 end()를 돌려준다(번호로 치면 n)        auto ia = std::find(stops.begin(), stops.end(), a);        auto ib = std::find(stops.begin(), stops.end(), b);        if (ia == stops.end() || ib == stops.end() || ib < ia) {            std::cout << "-1\n";            continue;        }        int i = ia - stops.begin(), j = ib - stops.begin();        std::cout << j - i << " " << times[j] - times[i] << "\n";    }}
Cmain.c · 29 行
#include <stdio.h>#include <string.h> static char stops[1000][11];static int times[1000];static int n; /* 이름이 처음 나오는 번호, 없으면 -1 */int index_of(const char *name) {    for (int i = 0; i < n; i++)        if (strcmp(stops[i], name) == 0) return i;    return -1;} int main(void) {    int q;    char a[11], b[11];    scanf("%d", &n);    for (int i = 0; i < n; i++) scanf("%10s", stops[i]);    for (int i = 0; i < n; i++) scanf("%d", &times[i]);    scanf("%d", &q);    for (int t = 0; t < q; t++) {        scanf("%10s %10s", a, b);        int i = index_of(a), j = index_of(b);        if (i == -1 || j == -1 || j < i) puts("-1");        else printf("%d %d\n", j - i, times[j] - times[i]);    }    return 0;}
Craykonmain.cray · 18 行
コンソール.行読み();stops = コンソール.行読み().空白除去().分ける(" ");times = コンソール.数読み();q = コンソール.行読み().数に();繰り返す (t = 0; t < q; t++){    p = コンソール.行読み().空白除去().分ける(" ");    i = stops.位置検索(p[0]); // 없으면 -1    j = stops.位置検索(p[1]);    もし (i == -1 || j == -1 || j < i)    {        コンソール.書く(-1);    }    でなければ    {        コンソール.書く(j - i + " " + (times[j] - times[i]));    }}