Оптимизация по скорости и размеру - Assembler
Формулировка задачи:
На асmp.ru есть "задача про XOR"
Моё решение не проходит по скорости на 16 тесте (более 10000 чисел) - вот оно
Лучшее решение на Паскале занимает 706 байт, у меня - 407. Подозреваю что нужно оптимизировать чтение из файла, но не уверен, что это поможет.
Какие идеи?
В рамках подготовки к чемпионату мира Кирилл придумал Ане задачу. Он написал N знаковых 32-битных чисел и попросил вычислить значение некоторого выражения S. Пусть a1, …, aN - все эти числа. Тогда выражение это
S = (a1 xor a2 xor … xor an) xor (b1 xor b2 xor … xor bn-1),
где
bi = F(ai, ai+1) xor F(ai, ai+2) xor … xor F(ai, an).
В этой формуле под знаком xor понимается побитовое «исключающее или», а F(a, b) = x - 1, где x - максимальная степень двойки, на которую делится нацело a-b, если a ≠ b, и F(a, b) = -1, если a = b. Все операции xor выполняются слева направо, если скобки не указывают иной порядок.
Аня, как большая специалистка в области циклов, быстро написала требуемую программу, однако программа работала слишком долго. Чтобы лучше разобраться в этом вопросе, она попросила вас написать программу, которая бы укладывалась в отведенное время. Помогите ей это сделать.
Входные данные
В первой строке входного файла INPUT.TXT содержится число N (1 ≤ N ≤ 105). В следующих N строках содержится N 32-битных знаковых целых чисел ai по одному на строке.Выходные данные
В выходной файл OUTPUT.TXT выведите значение выражения.var a: array[1..999999] of integer; i,j: integer; begin reset(input,'input.txt'); rewrite(output,'output.txt'); read(i); for j:=1 to i do read(a[j]); asm pushad mov edi,[i] dec edi mov ebx,dword[a+edi*4] jz @c @a:mov esi,[i] mov ebp,dword[a+edi*4-4] xor ebx,ebp @b:mov eax,ebp sub eax,dword[a+esi*4-4] cdq xor eax,edx sub eax,edx bsf ecx,eax setne al movzx eax,al shl eax,cl dec eax xor ebx,eax dec esi cmp esi,edi jnz @b dec edi jnz @a @c: mov [j],ebx popad end; write(j) end.
Решение задачи: «Оптимизация по скорости и размеру»
textual
Листинг программы
var a, b, i: Longint; begin Read(a); for i := 0 to 30 do b := b + a shr i and 1; Write(b) end.
Объяснение кода листинга программы
- В начале кода объявлены три переменные:
a
,b
иi
типа Longint. - Затем происходит чтение значения переменной
a
с помощью функции Read(). - Далее следует цикл от 0 до 30 с помощью выражения
for i := 0 to 30 do
. - Внутри цикла значение переменной
b
увеличивается на сумму значения переменнойa
и результата операцииshr i and 1
. - Значение переменной
b
сохраняется с помощью функции Write(). - Код завершается.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д