1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今回 paiza の「値の計算」の問題に挑戦!


問題概要

問題の内容

  • 複数種類の抵抗(名前と抵抗値が与えられる)がある。
  • それらの抵抗を直列または並列でつないで、1つの回路を作る。
  • 回路の全体抵抗を求め、小数点以下を切り捨てて出力する。

抵抗の接続の計算ルール

  • 直列 A + B
  • 並列 1 / (1 / A + 1 / B)

入力仕様

  • 1行目
    整数 N(抵抗の種類の数)

  • 2行目~(N+1)行目
    抵抗名 s_i(英大文字1文字)と抵抗値 w_i(整数)が与えられる。

    • 例: A 100

  • (N+2)行目
    整数 M(接続パターンの数)


  • (N+3)行目
    抵抗の接続方法を表す文字列 t_1 t_2 ... t_M
    • 空白で区切られた部分は 直列
    • 空白なしで並んだ文字列は 並列

出力仕様

  • 回路全体の抵抗値を 小数点以下切り捨て で整数出力する。



入力例:

3
A 100
B 200
C 300
2
AB C

出力例:

366






✅ OK例:

const rl = require('readline').createInterface({ input: process.stdin });

const lines = [];
rl.on('line', input => lines.push(input));

rl.on('close', () => {
    const N = Number(lines[0]);

    // 抵抗値マップを作成
    const sw = new Map();
    for (let i = 1; i <= N; i++) {
        const [s, w] = lines[i].split(' ');
        sw.set(s, Number(w));
    }

    const M = Number(lines[N + 1]);
    const t = lines[N + 2].split(' '); // 空白ごとに直列分割

    // --- 並列の抵抗を計算する関数 ---
    const parallel = (arr) => {
        let denom = 0;
        for (const x of arr) {
            denom += 1 / sw.get(x);
        }
        return 1 / denom;
    };

    // 直列の合計
    let total = 0;
    for (const part of t) {
        if (part.length === 1) {
            total += sw.get(part);      // 抵抗一個だけ → そのまま
        } else {
            total += parallel(part.split('')); // 並列
        }
    }

    console.log(Math.floor(total));
});

🔍 コードの流れ

入力を受け取る準備

  • readline で標準入力を読み込む
  • lines 配列に入力を保存

抵抗の種類と値をマップ化

  • 1行目 → N(抵抗の種類の数)
  • 次の N 行 → s w を読み取り、Map に「抵抗名 → 抵抗値」として保存

回路の構成を取得

  • N+1 行目 → M(接続情報の数)
  • N+2 行目 → 抵抗の接続方法(文字列)を取得し、空白で分割。
    空白区切り → 直列 のまとまりとして処理する

並列計算の関数を定義

  • 与えられた抵抗名の配列を受け取り
  • 1 / (1/a + 1/b + …) を計算して並列抵抗値を返す

直列合計を計算

  • 空白で分割された各部分を順番に処理
  • 1文字だけなら → そのまま抵抗値
  • 複数文字なら → 並列として計算して加算

結果を出力

  • 最終的な合計抵抗値を Math.floor で小数点切り捨て
  • console.log で出力





🗒️ まとめ

  • 入力処理
    • 辞書(Map)を使って「抵抗名 → 抵抗値」を素早く参照できるようにする。
  • 回路表現の分解
    • 空白で区切れば直列のまとまりになる。
    • 文字をまとめて見れば並列のまとまりになる。
  • 直列と並列の違い
    • 直列 → 単純に和をとる。
    • 並列 → 逆数を足し合わせて逆数を取る。
  • 実装の工夫
    • 並列計算は関数に切り出すと分かりやすい。
    • forreduce を使えば簡潔に書ける。
  • ポイント
    • 並列は必ず「逆数の和の逆数」になる。
    • 計算の最後に Math.floor で切り捨てるのを忘れない。




僕の失敗談(´;ω;`)と解決法🐈

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?