Можно ли так отнимать так индексы?
На вход программы поступает последовательность из N целых положительных чисел. Рассматриваются все пары различных элементов последовательности (элементы пары не обязаны стоять в последовательности рядом, порядок элементов в паре неважен). Необходимо определить количество произвольных пар, произведение чисел и разность индексов которых кратна 3. Описание входных и выходных данных В первой строке входных данных задаётся количество чисел N (1 ≤ N ≤ 10000). В каждой из последующих N строк записано одно натуральное число, не превышающее 10000. В качестве результата программа должна вывести одно число: количество найденных пар. Пример входных данных №1: 10 1 2 3 4 5 6 7 8 9 10 Выходные данных для приведенного выше примера: 3
var
a: array[1..10000] of integer;
N, i, j, x, b: integer;
begin
x := 0;
readln(N);
for i := 1 to N do
readln(a[i]);
for i := 1 to N - 1 do
for j := i + 1 to N do
if ((a[i] * a[j]) mod 3 = 0) and ((i - j) mod 3 = 0) then
x := x + 1;
writeln(x);
end.
Можно ли так отнимать индексы? ((i - j) mod 3 = 0) Это рабочий способ? Или есть какой-то более универсальный?
Ответы (2 шт):
Да, это рабочий способ.
Более оптимально же будет не проверять все разности индексов, а пройти только по нужным индексам с шагом 3
for i := 1 to N - 1 do
j := i + 3;
while i <= N do begin
if ((a[i] * a[j]) mod 3 = 0) then
x := x + 1;
inc(j, 3);
end;
Задачу можно решить в один проход за O(n) действий, что для n=10000 скорее необходимость, чем прихоть.
Тройка - простое число, чтобы произведение целых чисел делилось на него, необходимо и достаточно, чтобы один из сомножителей делился. Получается следующий алгоритм
- Для каждого индекса i ведем подсчет предшествующих чисел с индексами j ≡ i (mod 3)
- только тех, что делятся на 3 (Ai)
- всех таких чисел (Bi)
- Если текущее число делится на 3
- прибавляем к результату Bi
- иначе прибавляем Ai
var
count : array [0..2] of integer;
x, i, n, result: integer;
begin
result := 0;
read(n);
for i := 0 to n - 1 do
begin
read(x);
if x mod 3 = 0 then
begin
inc(count[i mod 3]);
inc(result, i div 3)
end
else
begin
inc(result, count[i mod 3])
end;
end;
writeln(result);
end.