You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

37 lines
1.3 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int a[N];
int Left[N], Right[N];
//最大公约数,辗转相除法
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
/**
*
5
12 36 24 18 48
6 6 6 12 6
*/
int main() {
int n;
cin >> n;
//读入数据
for (int i = 1; i <= n; i++) cin >> a[i];
//类似于递推式获取前1~(i-1)的最大公约数记录到Left[i]中。
for (int i = 1; i <= n; i++) Left[i] = gcd(Left[i - 1], a[i]);
//类似于递推式获取后n~(i+1)的最大公约数记录到Right[i]中。
for (int i = n; i >= 1; i--) Right[i] = gcd(a[i], Right[i + 1]);
//根据性质3可以通过左边最大公约和右边最大公约计算出去掉当前数字的最大公约
for (int i = 1; i <= n; i++) cout << gcd(Left[i - 1], Right[i + 1]) << " ";
//时间分析O(3*n)
//如果去掉每一个分别进行重新计算的话外层循环贡献n,内层还需要一层遍历所有剩余数字可以认为是O(N^2)级。
//这样通过性质3就可以实现平方级别时间复杂度到线性复杂度的进化。
//究其原因,就是空间换时间,把已知的结果保存下来,避开了重复的计算。
return 0;
}