-
Pythonでリストの全順列における特別な値Sの平均を計算するプログラム
問題の概要要素のリストが与えられたとき、次のアルゴリズムに従って値Sを計算できるものとします。while L のサイズが 1 より大きい間、繰り返す: a := L[0] b := L[1] L[1] を削除 L[0] := a + b + a*breturn L[0] mod (10^9 + 7)この問題では、リストLのすべての可能な順列(並べ替え)から計算されるSの値の平均を求める必要があります。例えば、入力
-
Pythonで回転配列の最大加重和を効率的に求めるプログラム
いくつかの要素からなる配列があるとします。この配列をさまざまな位置で回転させたとき、得られる加重和の最大値を求めたいと思います。配列 nums の加重和 S は、次の式で定義されます。$$\mathrm{S=\sum_{i=1}^{n}i \times nums[i]}$$つまり、各要素にその位置(インデックス+1)を掛けて足し合わせたものが加重和です。具体例入力が L = [5, 3, 4] の場合、出力は 26 になります。それぞれの回転状態における加重和は以下の通りです。配列が [5, 3, 4] の場合:5 + 2×3 + 3×4 = 5 + 6 + 12 = 23配列が [3, 4,
-
【Python】k個の監視ステーションで特定のポイントを監視できるか判定するプログラム
半径r以内の周辺環境を監視できるセンサーモジュールを想定してみましょう。このモジュールの監視円の円周上にある格子点の中には、監視が必要な対象がいくつか存在します。そこで、それらの特定のポイントのみを監視できるように、低消費電力のモジュールをk個配置することを考えます。半径の二乗(j)と低消費電力モジュールの数(k)が与えられたとき、すべてのポイントを正しく監視できるかどうかを判定するのが本記事の目的です。監視が可能であればtrueを、不可能であればfalseを返します。 たとえば、入力が半径の二乗(j) = 4、監視ポイント数(k) = 3だった場合、出力はFalseになります。 j = 4
-
Pythonでリンクリストの先頭からk番目と末尾からk番目のノードを交換する方法
問題の概要リンクリスト L と整数 k が与えられたとします。ここで求められているのは、先頭から k 番目のノードと末尾から k 番目のノードを入れ替え、その結果のリンクリストを返すことです。たとえば、入力が L = [1,5,6,7,1,6,3,9,12]、k = 3 の場合を考えてみましょう。先頭から3番目のノードは「6」、末尾から3番目のノードは「3」です。この2つのノードの値を入れ替えると、出力は [1,5,3,7,1,6,6,9,12] となります。解き方のアルゴリズムこの問題は、いわゆる「2つのポインタ(two-pointer)」テクニックを使うことで、リストを一度走査するだけで効
-
Pythonで数値リストに対する全クエリのkpr_sum(XOR総和)を効率的に求めるプログラム
数値のリスト nums と、複数のクエリを含むリストが与えられるとします。各クエリ queries[i] は [k, p, r] という3つの要素から構成され、それぞれのクエリに対して kpr_sum を計算する必要があります。 kpr_sum は次の数式で定義されます。 $$\mathrm{kpr\_sum} = \sum_{i=P}^{R-1}\sum_{j=i+1}^{R}\left(K \oplus (A[i] \oplus A[j])\right)$$ 計算結果が非常に大きな値になる場合は、109+7 で割った余り(モジュロ)を返します。 入力例と出力例 たとえば、入力が nums
-
数値nが「Weird(奇妙)」かどうかを判定するPythonプログラム
問題概要 整数nが与えられたとき、その数値が「Weird(奇妙)」であるかどうかを判定するPythonプログラムを作成します。この問題における判定条件は以下のとおりです。 数値が奇数である場合 → 「Weird」 数値が偶数で、範囲2〜5にある場合 → 「Not Weird」 数値が偶数で、範囲6〜20にある場合 → 「Weird」 数値が偶数で、20より大きい場合 → 「Not Weird」 例えば、入力がn = 18の場合、18は偶数であり範囲6〜20に含まれるため、出力は「Weird」になります。 解き方のアプローチ この問題を解くには、以下の手順で条件分岐を行います。 nが奇数
-
【Python】Union-Findでスワップ後のハミング距離を最小化する方法
問題概要 同じ長さを持つ2つの整数配列 src と tgt、および配列 allowedSwaps が与えられるとします。allowedSwaps[i] にはペア (ai, bi) が含まれており、これは配列 src のインデックス ai にある要素と、インデックス bi にある要素を入れ替えられることを意味します。なお、特定のペアのインデックスは何度でも、任意の順序で入れ替えて構いません。 ここで、同じ長さの2つの配列におけるハミング距離とは、要素が互いに異なる位置の個数のことです。配列 src に対して任意の回数のスワップ操作を実行した後の、src と tgt の最小ハミング距離を求めます。
-
Pythonでi+j+kがnと異なるトリプレットのリストをリスト内包表記で求める方法
3つの数 i、j、k と、もう1つの数 n が与えられているとします。このとき、「i+j+k が n と等しくない」条件を満たすすべてのトリプレット (x, y, z) のリストを作成するのが課題です。この問題は、Pythonのリスト内包表記を使うことで、簡潔かつ効率的に解くことができます。 例えば、入力が i = 1、j = 1、k = 2、n = 3 の場合、出力は次のようになります。 [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 2]] 解法の
-
Pythonで積が等しくなるタプル(a×b=c×d)の個数を求めるプログラム
問題の概要 正の整数が重複なく格納された配列 nums が与えられます。このとき、a × b = c × d を満たすタプル (a, b, c, d) の総数を求めます。ただし、a、b、c、d はすべて nums の要素であり、4つの値は互いに異なる必要があります。 たとえば入力が nums = [2, 3, 4, 6] の場合、出力は 8 になります。条件を満たすタプルは次の 8 通りです。 (2, 6, 3, 4)、(2, 6, 4, 3)、(6, 2, 3, 4)、(6, 2, 4, 3)、(3, 4, 2, 6)、(4, 3, 2, 6)、(3, 4, 6, 2)、(4, 3, 6,
-
Pythonで列を並べ替えた後に最大の部分行列を見つける方法
問題概要 m×n のバイナリ行列(各要素が 0 か 1 のみで構成される行列)が与えられます。この行列の列は、任意の順序で自由に入れ替えることができます。列の並べ替えを行った後、すべての要素が 1 であるような最大の部分行列を見つけ、その面積を求めるのがこの問題の目的です。 たとえば、入力が次のような行列だったとしましょう。 001111101 このとき出力は 4 になります。列を入れ替えることで、次のような行列が得られるからです。 110111010 オレンジ色で示した部分が最大の部分行列で、1 が 4 つ並ぶ 2×2 の正方形になっています。面積は 4 です。 解法のステップ この問題は、
-
Pythonでグリッド上の最短経路を探索する:BFSによる最短移動回数の求め方
はじめに 本記事では、記号が書かれたグリッド(マス目)の中で、現在位置からゴールまでの最短移動回数を求めるPythonプログラムを紹介します。この種の迷路・経路探索問題は、幅優先探索(BFS)を用いることで効率的に解くことができます。 グリッドの記号の意味 グリッドには以下の4種類の記号が含まれ、それぞれ次のような意味を持ちます。 # … ゴールとなるセル。ここへの到達を目指します。 O … 自由に通行できる空きセル。 * … 自分の現在位置。 X … 障害物のあるセル。通過することはできません。 問題の概要 与えられたグリッド上で、現在位置「*」からゴール「#」まで到達するために必要
-
Pythonで同時に成立する部屋移動リクエストの最大数を求めるプログラム
寮には0からn-1までの番号が付けられたn個の部屋があるとします。各部屋の学生は別の部屋へ引っ越したいと考えており、そのために複数の移動リクエストを提出します。ただし、寮の席が空いたままになることは許されず、移動を希望する学生の代わりに別の学生がその部屋に入ってくれる場合にのみ、移動リクエストが受理されます。そこで本記事では、与えられたリクエストの中から、実際に同時に満たすことのできるリクエストの最大数を求める方法を解説します。 例えば、入力が n = 3、requests = [[0,2],[1,0],[2,1]] の場合、出力は 3 になります。これは次のように3件すべての移動が成立する
-
Pythonで整数をゼロに変換するための最小ビット演算回数を求めるプログラム
問題概要 整数 n が与えられます。この n を、以下の2種類の操作を何度でも繰り返し適用して 0 に変換することを考えます。 操作1: n の2進表現の中で最も右側のビット(最下位ビット)を選び、その値を反転する。 操作2: 第 i ビットについて、「第 (i−1) ビットが 1 であり、第 (i−2) ビットから第 0 ビットまですべて 0 である」という条件を満たす場合にのみ、そのビットを反転できる。 目的は、n を 0 に変換するために必要な最小の操作回数を求めることです。 具体例 入力が n = 6 の場合を考えてみます。6 の2進表現は 110 なので、出力は 4 となりま
-
Pythonで辞書(文字列リスト)からターゲット文字列を形成する方法の数を求めるプログラム
問題の概要 すべて同じ長さの文字列で構成されるリスト words と、文字列 target が与えられます。次のルールに従い、words を使って target を生成することを考えます。 target は左から右へ順に構築します。 target の i 番目(0始まり)の文字を得るには、target[i] が words[j][k](words の j 番目の文字列の k 番目の文字)と一致するとき、その文字を選択できます。 ある文字列の k 番目の文字を一度使用すると、それ以降はどの文字列でも x ≤ k を満たす x 番目の文字は使用できません。 この手順を target 全体が完成す
-
Pythonで繰り返し整数を分配できるか判定するプログラムの実装方法
問題の概要 配列 nums があるとします。この配列には最大50種類の一意な値が含まれています。さらに、quantity という別の配列も与えられ、quantity[i] は i 番目の顧客が注文した数量を表します。ここで、次の条件をすべて満たすように nums を分配できるかどうかを判定する必要があります。 i 番目の顧客は、ちょうど quantity[i] 個のアイテムを受け取ること i 番目の顧客が受け取るアイテムの値は、すべて同じであること すべての顧客が満足すること たとえば、入力が nums = [5,1,2,2,3,4,4,3,3]、quantity = [2,2,3] の場
-
Pythonで配列の偏差を最小化するプログラムの実装方法
問題の概要 配列 nums が与えられます。配列内の任意の要素に対して、次の2種類の操作を何度でも実行できます。 偶数の要素は 2 で割る 奇数の要素は 2 倍する ここで、配列の「偏差」とは、配列内の任意の2つの要素間の差のうち最大のものを指します。求めたいのは、操作を何度か実行した後に配列が取りうる偏差の最小値です。 具体例 入力が nums = [6,3,7,22,5] の場合、答えは 5 になります。実際の操作の流れは次のとおりです。 1回目の操作:3 を 2 倍して [6,6,7,22,5] 2回目の操作:5 を 2 倍して [6,6,7,22,10] 3回目の操作:22 を
-
Pythonでエッジの重みに上限があるパスの存在を判定するプログラム
問題概要 n 個のノードを持つ無向重み付きグラフを考えます。グラフは edgeList で与えられ、edgeList[i] は (u, v, w) の3つの要素からなり、「u と v の間に距離 w の辺が存在する」ことを表します。 さらに、query[i] が (p, q, lim) の形式を持つクエリ配列も与えられます。各クエリは「p から q へ(直接または他のノードを経由して)、距離が lim 未満の経路は存在するか?」を問うものです。すべてのクエリに対する True / False の結果を配列として返す必要があります。 具体例 たとえば、次のようなグラフが入力として与えられたとし
-
Pythonでバイナリ配列にk個の連続する1を作るための最小隣接スワップ回数を求めるプログラム
問題概要0と1のみから構成されるバイナリ配列 nums と整数 k が与えられます。1回の操作では、隣り合う2つの要素を選んで値を入れ替える(スワップする)ことができます。配列の中に k個の連続する1 が存在する状態を作るために必要な最小の操作回数を求めるのが、この問題の目的です。例えば、入力が nums = [1,0,0,1,0,1,0,1]、k = 3 の場合を考えてみましょう。このときの出力は 2 となります。1回目のスワップで [1,0,0,1,0,1,0,1] から [1,0,0,0,1,1,0,1] へ並べ替え、さらに2回目のスワップで [1,0,0,0,1,1,1,0] とするこ
-
Pythonで配列の要素から最大XORを求めるプログラムの作成方法
非負の整数だけを含む配列 nums と、複数のクエリをまとめた配列 queries が与えられるとします。queries[i] はペア (xi, mi) を表しています。i 番目のクエリに対する答えは、mi 以下の nums の要素の中から選んだ任意の要素と xi のビット単位 XOR の最大値です。もし nums のすべての要素が mi より大きければ、その答えは -1 となります。 最終的には、queries と同じ長さの配列 answer を返す必要があります。answer[i] には i 番目のクエリの答えを格納してください。 入力例と出力例 例として、入力が nums = [0,1,
-
C++で文字列のK類似性を求めるプログラム|最小スワップ回数をBFSで探索
問題の概要2つの文字列 s と t があるとします。s 内の2つの文字の位置をちょうどK回入れ替えることで t と同一の文字列にできるとき、これらの文字列は「K類似(K-similar)」であると定義されます。ここで、互いにアナグラム(同じ文字で構成された並べ替え)の関係にある2つの文字列 s と t が与えられるので、s と t が K類似となる最小の K を求めましょう。例えば、入力が s = abc、t = bac の場合、出力は 1 となります。解決アプローチ:幅優先探索(BFS)この問題は、文字列の各状態をグラフのノードとみなし、「1回のスワップ」をエッジとして幅優先探索(BFS)を