0

したがって、基本的には、次の図を確認してください。

画像

これは 4x5 のグリッドの説明ですが、実際の課題ではグリッドの寸法を入力する必要があります。つまり、私の仕事は、ターン数 (この場合は赤い点) を計算するプログラムを作成することです。開始位置は常に左下隅です。男は時計の矢印(「右」)で動いています。

プログラムの入力/出力は次のとおりです。グリッドの寸法を入力します: 4 5 (例)

方向の変化量を出力します。7

だから、私はそれがどのように行われたのか全くわかりません。私が見た解決策は次のとおりです。

#include <iostream>
#include <cmath>
using namespace std;
int main() {
    long long n, i,pom,m;
    int k,br=0;

    cin>>n>>m;
    if(n>m) {
        int pom=n;
        n=m;
        m=n;
    }
    if(n+1>=m)
        cout<<(n-1)+(m-1);
    else
        cout<<(n-1) +(n-1)+1;

    return 0;
}

しかし、私は次の例を理解していません...誰かが何が起こっているのか説明できますか? または、この問題を解決する他の方法はいつでも大歓迎です。

4

3 に答える 3

2
int res = 0;
if(height == width)
    res = height * 2 - 2;//when height is odd than you will have 2 rows with single red dot
                           //when height is even you will have one row without red dot (all the rest have 2 red dots.
else if (width > height)
   res = height * 2 - 1;//one rows with 1 red dot the rest with 2 red dots.
else //height > width
   res = width * 2 - 2// 2 columns with one red dot and the rest with 2 red dots.
于 2013-03-03T11:27:39.693 に答える
1

私は C++ の専門家ではないので、コードを理解するのに役立ちません。しかし、ここで状況を理解するのに役立つことは間違いありません。状況は、ターン数が 2 つの次元の 1 つだけに依存するということです。どちらが少ないですか。したがって、ターン数は、小さい方の次元とその側のボックスの数によって異なります。これは、4X5 配列を使用する場合の図であるため、幅をどれだけ増やしても。高さが4である限り、ターン数は7のままです。しかし、幅を 4 から 3 に減らすと、巻き数は幅に依存します。

次に点数について。両方の寸法が同じで奇数の場合、寸法を 2A+1 と仮定すると、巻数は 4*A になります。

1 つの寸法が小さい場合、寸法が同じで偶数の場合、寸法が 2*A であると仮定すると、巻数は 4A-2 になります。

小さい方の寸法が偶数の場合、寸法を 2*A とすると、巻数は 4A-1 になります。

小さい方の次元が奇数の場合、次元を 2A+1 とすると、巻数は 4A+1 になります。

これが独自の新しいコードで機能するかどうかを確認してください。

于 2013-03-03T11:51:00.350 に答える
1

nこのコードは、条件付きで andmを make にスワップしn <= mます。

if(n>m) {
    int pom=n;
    n=m;
    m=n;
}

それを考えると、条件n+1>=mは と同等n == m || n + 1 == mです。

(n-1)+(m-1)式との両方(n-1) +(n-1)+1で に対して同じ結果が得られることに注意してくださいn + 1 == m

したがって、実際にチェックする必要はありませんn + 1 == m。重要なのは特殊なケースだけn == mです。の場合n == mは、式を使用する(n-1)+(m-1)か、単にを使用できます2 * n - 2。それ以外の場合は、式 を使用する(n-1) +(n-1)+1か、単にを使用し2 * n - 1ます。

コードを書き直すには:

int calculate_number_of_turns(int m, int n)
{
    if (m == n)
        return 2 * n - 2;
    else
        return 2 * std::min(m, n) - 1;
}

編集:

事前に数学を知らずにコードを最初から書きたい場合は、最初に再帰関数を書くことができます。

の場合n = 2、答えは 3 (3 ターン) であることが簡単にわかります。の場合m = 2、答えは 2 です。それ以外の場合 (n > 2および と仮定m > 2)、計算には異なる引数に対して同じ関数を呼び出すことが含まれます。

int calculate_number_of_turns(int m, int n)
{
    if (n == 2)
        return 3;
    else if (m == 2)
        return 2;
    else
        return calculate_number_of_turns(???, ???);
}

写真のパスを開始し、2 番目のターンを行った直後に停止することを想像してください。画像を上下逆さまにすると、 と 高さを 1 減らしたようになります。同じ関数を呼び出すと、最初の 2 回転に加えm - 1, n - 1て、残りの回転数が計算されます。

int calculate_number_of_turns(int m, int n)
{
    if (n == 2)
        return 3;
    else if (m == 2)
        return 2;
    else
        return 2 + calculate_number_of_turns(m - 1, n - 1);
}

さて、この再帰関数をより単純な形式に変換することはそれほど複雑ではありません (終了条件が成立するまで、関数が自分自身を呼び出す回数を計算するだけです)。

于 2013-03-03T11:51:07.690 に答える