https://www.hackerrank.com/contests/101hack45/challenges/the-chosen-one
找出一个数字,使得,数组中只有一个数字不是这个数的约数,而且其他数都是这个数的约数。
如果暴力枚举每一个i,表示,就是要排除这个数字,那么,需要找到一个数能被剩下的数都整除。那么最优解就是gcd了。
因为他们的gcd,就是最大公约数,被排除的那个数字最不可能整除这个数。
所以快速求剩下数字的gcd就需要预处理pre[i]表示前i个数的gcd,last[i]表示i--n的gcd,然后再gcd
注意特判n = =
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 1e5 + 20; LL pre[maxn]; LL last[maxn]; LL a[maxn]; void work() { int n; scanf("%d", &n); for (int i = 1; i <= n; ++i) { cin >> a[i]; } pre[0] = 1; pre[1] = a[1]; for (int i = 2; i <= n; ++i) { pre[i] = __gcd(pre[i - 1], a[i]); } last[n + 1] = 1; last[n] = a[n]; for (int i = n - 1; i >= 1; --i) { last[i] = __gcd(last[i + 1], a[i]); } for (int i = 1; i <= n; ++i) { LL t; if (i == 1) { t = last[i + 1]; } else if (i == n) { t = pre[i - 1]; } else t = __gcd(pre[i - 1], last[i + 1]); if (a[i] % t != 0) { cout << t << endl; return; } } cout << a[n] + 1 << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }