【C++入門】2つの異なる区間から相異なる2点を見つけるプログラム
問題概要
x軸上の2本の線分を表す2つの区間 (l1, r1) と (l2, r2) が与えられます。ここで l1 < r1、l2 < r2 が成り立ちます。これらの線分は互いに交差したり、部分的に重なったり、完全に一致したりする可能性があります。
この問題では、a が区間 (l1, r1) 内に含まれ、b が区間 (l2, r2) 内に含まれ、かつ a と b が異なる値となるような2つの数 a、b を見つけることが求められます。
たとえば、l1 = 2、r1 = 6、l2 = 3、r2 = 4 が入力された場合、a = 2、b = 3 を出力できます。もちろん、条件を満たす他の組み合わせも正解として成立します。
解法のアルゴリズム
この問題は非常にシンプルな発想で解くことができます。各区間の左端(始点)に注目し、以下の手順に従います。
もし l1 と l2 が等しい場合:
l1 を 1 増やす
l1 と l2 を出力するなぜこれで正しいのか考えてみましょう。l1 と l2 が等しい場合でも、l1 < r1 という前提条件があるため、l1 を 1 増やした値は依然として区間 (l1, r1) の中に含まれます。また、l1 + 1 と l2 は必ず異なる値になります。一方、l1 と l2 が最初から異なる場合は、そのまま出力すればよいだけです。
実装例(C++)
理解を深めるために、以下の実装を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
void solve(int l1, int r1, int l2, int r2) {
if (l1 == l2)
l1++;
cout << l1 << ", " << l2;
}
int main() {
int l1 = 2;
int r1 = 6;
int l2 = 3;
int r2 = 4;
solve(l1, r1, l2, r2);
}入力
2, 6, 3, 4
出力
2, 3
まとめ
このアルゴリズムの計算量は O(1) であり、定数時間で答えを求められる非常に効率的な手法です。区間の左端同士を比較するだけで、必ず相異なる2点を見つけられる点がポイントです。競技プログラミングにおいても、こうした端点の性質を利用したシンプルな考察は頻出テクニックなので、ぜひ覚えておきましょう。
-
C++で3つの点が同一直線上にあるかどうかを判定するプログラム
3つの異なる座標を持つ点が与えられ、それらの点が同一直線上に並んでいるかどうか(共線性・コリニア)を判定するのが本記事のテーマです。3つの点がすべて同じ直線上に乗っている場合、これらの点は「共線(collinear)」であるといいます。逆に、異なる直線上に配置されている場合は共線ではありません。以下の図は、共線な点と共線でない点の違いを示したものです。入力例と出力例入力1x1 = 1, x2 = 2, x3 = 3, y1 = 1, y2 = 4, y3 = 5出力1no points are not collinear入力2x1 = 1, y1 = 1, x2 = 1, y2 = 4, x3
-
C++で2本の直線の交点を求めるプログラムの書き方
直線ABを定義する2点A・Bと、直線CDを定義する2点C・Dが与えられたとき、この2つの直線の交点を求めるのが課題です。 注意 − すべての点は、X座標とY座標を持つ2次元平面上にあるものとします。 図では、A(a1, a2)とB(b1, b2)を通る直線、C(c1, c2)とD(d1, d2)を通る直線という、互いに異なる2つの直線が描かれており、P(p1, p2)がその交点を表しています。 交点の求め方 まず、2点を通る直線を「ax + by = c」の形の方程式で表します。各点の座標を使って、次のように係数を計算します。 A1 = b2 - a2 B1 = a1 - b1 C1 =