안녕하세요 여러분, 오늘은 심각한 문제 해결 방법을 포스팅하려고 합니다.
문:
이 질문은 대중화 그룹의 세 번째 질문이지만 실제로는 그리 어렵지 않습니다. 하지만 폭력을 좋아하는 사람들에게는 그렇지 않습니다 .
데이터 규모를 살펴보십시오.
데이터의 경우 ;
데이터의 경우 .
폭력적이라면 하나는 9억 어레이 가 따라가지 못한다는 것이고, 다른 하나는 시간 복잡도를 견딜 수 없다는 것이다.
그러나 여기에 하나의 얕고 약한 코드가 있습니다.
#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을 측면 길이라고 하고 다음을 계산해 봅니다.
상단:
왼쪽에:
오른쪽으로:
아래에:
그렇지 않은 경우 내부에 하나의 레이어를 밀어 넣습니다.
즉, 이 알고리즘 은 대부분의 경우 이 행렬의 수준 으로 푸시되어야 하므로 시간 복잡도는 .
암호:
#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가지 경우를 계산할 수 있습니다.
글쎄, 여기에 아이디어가 있습니다. 쓰자!
암호:
#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;
}
글쎄, 오늘 나는 심각한 문제 해결을 게시했는데 매우 좋은 것 같습니다. 안녕!