みなさん、こんにちは。今日は深刻な問題の解決策を投稿します。
ポータル:
この問題は普及班の3問目ですが、実はそれほど難しくありません。でも、まあ、暴力が好きな人向けではありません。
データ スケールを見てみましょう。
データについて は、 ;
データについて は、 .
暴力的な場合、1 つは9 億の配列が追いつかないことであり、もう1 つは時間の複雑さが許容できないことです。
ただし、これは浅くて弱いコードです。
#include <iostream>
using namespace std;
int a[105][105];
int main() {
int n, x, y, m = 1; cin >> n >> x >> y;
for (int i = 0; i < n / 2 + 1; ++i) {
for (int j = i; j < n - i; ++j)a[i][j] = m++;
for (int j = i + 1; j < n - i; ++j)a[j][n - i - 1] = m++;
for (int j = n - i - 2; j > i; --j)a[n - i - 1][j] = m++;
for (int j = n - i - 1; j > i; --j)a[j][i] = m++;
}
cout << a[x - 1][y - 1] << endl;
}
だから、別の方法を求めてください。
この質問は、ルールが次のようになるたびに、関数を定義する再帰と見なすことができます。
最外層の場合、辺の長さを n として、次のように計算してみてください。
上に:
左に:
右側に:
下:
そうでない場合は、1 つのレイヤーを内部にプッシュします。
つまり、このアルゴリズムは、ほとんどの場合、この行列のレベルまでプッシュする必要があるため、時間計算量はです。
コード:
#include<iostream>
using namespace std;
int f(int n, int i, int j) {
if (i == 1)return j;
if (j == n)return n + i - 1;
if (i == n)return 3 * n - 2 - j + 1;
if (j == 1)return 4 * n - 4 - i + 2;
return f(n - 2, i - 1, j - 1) + 4 * (n - 1);
}
int main() {
int n, i, j; cin >> n >> i >> j;
cout << f(n, i, j) << endl;
}
私:しかし、私はまだ不満があり、それを に変えたいと思っています.
聴衆: お元気ですか、コードについて考えたいと思います! これはまったくできません!
私:しかし、この番号がどのリングにあるのか、このリングの最初の番号または前のリングの最後の番号を直接特定する方法はありますか?
観客:。. .
...
長い導出の後、私はそれを理解しました!
上記は段落であり、分析が正式に開始されます。
どのリングに属しているかを見つけるのは比較的簡単です。エッジからそれぞれ i と j の距離を確認するだけです。レイヤーの数を とすると、式は次のように簡略化されます。
しかし、実際に判断文を使うのは、上下左右の4方向のうちどれが正しいかを知るためです。
このリングの最初の数を見つけるには、関係式を導出する必要があります。
(ここで、私は友人に一言言います: はい、それは私たちの先生が教えた「代数テスト」です)
前のリングの最後の数は、このレイヤーの外側の各レイヤーの周長の合計であるため、次のように設定します。
このように、上記のポイントに従って4つのケースを計算できます。
さて、ここにアイデアがあります。書きましょう!
コード:
#include<iostream>
using namespace std;
int main() {
int n, i, j, f, flag, m, ans, c; cin >> n >> i >> j;
if (min(i, j) < (n + 1) - max(i, j)) {
if (i < j)flag = 1;
else flag = 4;
}
else {
if (i > j)flag = 3;
else flag = 2;
}
f = min(min(i, j), (n + 1) - max(i, j));
m = 4 * (f - 1) * (n - f + 1);
c = (n - 1) - 2 * (f - 1) + 1;
i -= f - 1, j -= f - 1;
if(flag == 1)ans = m + j;
else if(flag == 2)ans = m + c + i - 1;
else if(flag == 3)ans = m + 3 * c - j - 1;
else ans = m + 4 * c - i - 2;
cout << ans << endl;
return 0;
}
さて、今日は深刻な問題の解決策を投稿しました。とても良いと思います。さようなら!