Оптимизация алгоритма "Забавная игра"
Помогите, пожалуйста, оптимизировать алгоритм по времени выполнения. Признаюсь, переписал его с питона, потому что мой выполнялся ещё дольше. Мне кажется нужно концептуально поменять решение. Вот задание:
Забавная игра
Вы с друзьями играете в следующую игру. Друзья пишут на доске подряд N натуральных чисел. Ваша задача — найти как можно больше подряд идущих чисел, которые бы делились на одно и то же число, большее 1. Так как вручную искать ответ сложно, вы решили написать программу, которая сделает работу за вас.
Входные данные
В первой строке входных данных задано число N(1 ≤ N ≤ 100000). Во второй строке записано через пробел N целых чисел A1...AN(1 ≤ Ai ≤ 1000, 1 ≤ i ≤ N). Это те самые числа, которые написали ваши друзья. Они даны в том же порядке, в котором они расположены на доске.
Выходные данные
Ваша программа должна вывести одно целое число — наибольшее количество подряд идущих чисел заданной последовательности, которые бы делились на одно и то же натуральное число, большее 1.
Пример: Ввод 3 6 10 15 Вывод 2
Моя программа:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <deque>
#include <iterator>
using namespace std;
using lli = long long;
using lld = long double;
using ulli = unsigned long long;
using usi = unsigned short;
template <typename T2>
T2 gcd(T2 a, T2 b)
{
if (a < b) swap(a, b);
if (b == 0) return a;
return gcd(b, a % b);
}
int main() {
lli n, mx = 0, cur_g;
cin >> n;
vector <lli> a;
lli x;
for (lli i = 0; i < n; i++) {
cin >> x;
a.push_back(x);
}
for (lli i = 0; i < n; i++) {
cur_g = a[i];
if (n - i < mx) break;
lli p = 0;
for (lli j = i; j < n; j++) {
cur_g = gcd(cur_g, a[j]);
if (cur_g == 1) break;
++p;
if (mx < p) mx = p;
}
}
cout << mx;
}
Ответы (1 шт):
Ну, простое по мере чтения построение массива делимости на 11 простых чисел, укладывающихся в делители 1000. После чего 11 проходов по этим массивам. O(N), несмотря на 12 в сумме проходов :)
#include <iostream>
#include <iomanip>
using namespace std;
int p[11] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
int v[11][100000] = {};
int main()
{
int N;
cin >> N;
for(int i = 0; i < N; ++i)
{
int M;
cin >> M;
for(int j = 0; j < 11; ++j)
if (M%p[j] == 0) v[j][i] = 1;
}
int M = 0;
for(int j = 0; j < 11; ++j)
{
int K = 0;
for(int i = 0; i < N; ++i)
if (v[j][i] == 0)
{
if (M < K) { M = K; }
K = 0;
}
else ++K;
if (M < K) M = K;
}
cout << M;
}
благополучно проходит https://informatics.msk.ru/mod/statements/view.php?id=7847