C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で開始座標から目標座標への移動が可能かどうかを判定する方法

2つの座標 (sx, sy) と (tx, ty) が与えられたとき、開始点から終点へ移動できるかどうかを判定する問題を考えてみましょう。ここでいう「移動」とは、ある点 (x, y) を (x, x+y) または (x+y, y) のいずれかに変換する操作のことです。

例えば、入力が (1, 1) と (4, 5) の場合、答えは true(移動可能)となります。これは、(1, 1) → (2, 1) → (3, 1) → (4, 1) → (4, 5) という順番で移動できるためです。

アルゴリズムの考え方

この問題は、ユークリッドの互除法と同じ発想で逆算的に解くのが効果的です。前進する操作は座標を増やすだけなので、目標座標側から剰余を取っていくことで、開始点に一致させられるかを効率よく調べられます。手順は以下の通りです。

  • tx > sx かつ ty > sy の間、次の処理を繰り返します。
    • tx > ty の場合:tx := tx mod ty
    • それ以外の場合:ty := ty mod tx
  • ループを抜けたら、次の条件のいずれかを満たしていれば true を返します。
    • sx == tx かつ sy <= ty かつ (ty − sy) mod tx == 0
    • sy == ty かつ tx >= sx かつ (tx − sx) mod ty == 0

この方法なら、座標の値が非常に大きい場合でも、単純に1ステップずつシミュレーションする方式と比べて大幅に高速に判定できます。

C++での実装例

理解を深めるために、実際の実装を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
bool solve(int sx, int sy, int tx, int ty) {
    while(tx > sx && ty > sy){
        if(tx > ty){
            tx %= ty;
        }else ty %= tx;
    }
    return (sx == tx && sy <= ty && (ty - sy) % tx == 0) || (sy == ty && tx >= sx && (tx - sx) % ty == 0);
}
main(){
    cout << solve(1,1,4,5);
}

入力

1, 1, 4, 5

出力

1

出力が 1(true)となっており、(1, 1) から (4, 5) への移動が可能であることが確認できました。

  1. C++で与えられた点から作成できる四角形の数を求める方法

    四角形とは? 四角形(クアドララテラル)とは、ユークリッド平面上で4つの頂点と4つの辺を持つ多角形のことを指します。「4-gon」という呼び方もあり、正方形や長方形なども四角形の一種に含まれます。 本記事では、与えられた点から作成できる四角形の数を求める手法について解説します。この問題では、直交座標系(XY平面)上に与えられた4つの点 (x, y) を用いて、いくつの四角形を構成できるかを求めます。まず、具体的な入力例と出力例を見てみましょう。 入力 : A( -2, 8 ), B( -2, 0 ), C( 6, -1 ), D( 0, 8 ) 出力 : 1 説明 : 作成できる四角形は1つだ

  2. C++で二分木がSumTree(総和木)かどうかを判定する方法

    ここでは、与えられた二分木が「SumTree(総和木)」であるかどうかを判定する方法を解説します。まずは、SumTreeとはどのような木なのかを確認しておきましょう。 SumTreeとは SumTreeとは、すべての内部ノードが「左の子と右の子の値の合計」を保持する特殊な二分木です。木の根(ルート)には、それより下位に存在する全要素の合計値が格納されます。なお、葉ノードのみからなる木や空の木も、定義上はSumTreeとみなされます。以下はSumTreeの一例です。 例えば上図の木では、根の値26が左部分木(10 + 4 + 6 = 20)と右部分木(3 + 3 = 6)の合計と一致しており