Pull to refresh

Comments 104

UFO just landed and posted this here
наверное нужно найти формулу где бы фигуриовали только n и арифметические операции, которая на выходе давала бы или 0 или 1
Только арифмитические операции.
UFO just landed and posted this here
В TP нет конструкции try...except
n mod (n-1) ? Но это только для положительных.
тогда abs(n) mod (abs(n)+1)
abs(n) mod (abs(n)+1) = abs(n)
abs(n) mod abs(n-1) и для отрицательных :)
UFO just landed and posted this here
Простите, а какая? Логическая?
UFO just landed and posted this here
a mod b = a - (a div b) * b
Корень же можно считать двояко. В смысле с одной стороны это просто сумма ряда до определенного места, и вот тут то проблема.
Каждое слагаемое ряда мы можем посчитать при помощи арифметической операции. (будет умножение, вычитание и деление), но вот можем ли мы сложить. Если считать что ряд мы считаем всегда до определенного члена, то тогда корень, как и любое другое возведение в степень есть операция арифметическая, ровно как и использование синуса, косинуса, прочей тригонометрии и вообще функций, получаемых при помощи арифметических операций из элементарных. (рекурсивненькое определение получилось)
Вот примерно так.
что за бред?
mod - это остаток от деления, этому классе во 2 учат
Зачем здесь умножение на 1 ума не приложу)
видимо чтобы была арифметическая операция %)
Чтобы определить, равно ли число n нулю.
1* компилятором проигнорируется
if это не арифметическая операция
Хех, ступил, однако :)
Бывает, конец рабочего дня %)
n := n*n; //на случай если отрицательное число и нельзя использовать модуль
answer := ((2*n+1)div(n+1)mod(n+1));
Допустим, что n=5, тогда получается 0. Или я где-то спутал?
51 div 26 = 1 (округление в сторону 0)
1 mod 26 = 1- (1 div 26) * 26 = 1 - (0) * 26 = 1
нужно значит проверить равно ли n*n + 1 ебенице.
answer := 2 - (n*n + 2) div (n*n + 1)
Если n=0, то получаем что 2 делим на один, в итоге два. 2 - 2 = 0.
Если n>0, то обозначим к = n*n + 1 и к+1/k < 2.
Значит (n*n+2) div (n*n+1) = 1, и 2 - 1 = 1.
Вуаля. Только единственная проблема, что при возведении n в квадрат будет переполнение, но я думаю подобную жесть с ограничениями в данном случае можно не рассматривать.
n>0 в смысле n<>0. не поймите неправильно.
чему-чему равно n*n + 1?? :)
шутка. простите не сдержался...
Да, ебеница меня тоже порадовала, надо запомнить :)
Однозначно равна ебенице =)
Кстати, нашел баг: если ввести допустим 123123, то ответ не равен единице...
Можно поподробнее? Почему он будет равен не единице?
1231232 + 1<1231232 + 2<(1231232 + 1)*2
значит 1231232+2 div 1231232+1 = 1
2-1 = 1;
Про проблемы переполнения я уже написал.
Написал программку на Free Pascal, все работает замечательно, только вот ввел "от балды" 123123 и получил ответ 2.
Может и переполнение... (с числом 9999999 получил корректный ответ)
для n >= 0: round(n / (n+1) + 0.5); в общем случае добавить abs()
Или trunc вместо round, уже не помню, в общем n/(n+1) всегда <0.5 для 0 и >=0.5 для n>1
С каких пор round есть орифметическая операция?
ну тогда n:=n*n; n:=(n+(n+1)div 2)div(n+1);
abs(n xor 0), у кого есть паскаль попробуте плз
Выводит n вместо 1
еще один вариант с использованием только модуля:
1-(abs(n+1)+abs(n-1)-2*abs(n))/2
или так если слегка упростить:
=== abs(n)+1 - abs(n+1)/2 - abs(n-1)/2
можно еще так:
=== ceil(abs(atan(n))
UFO just landed and posted this here
это решение хорошо тем, что не содержит деления и даже умножения на n. Есть только инкременты, декременты и битовые сдвиги. Даже взятие по модулю сводится к битовым операциям.
UFO just landed and posted this here
Всё проще: выводим Sin^2 (Pi*n/2)
ой, как ступил то! :( надо спать уже ложится...
UFO just landed and posted this here
Пока не появляются отрицательные n :) Но это уже решается просто
Например 1-0^(n*n)
p.s. извиняюсь за количество ответов :)
да, так круче :)
я полчаса ничо не мог делать, голову ломал :)
Это того стоило :)
Думаю 1-0^(n*n) это действительно самый правильный ответ (ибо он очень простой и всего 3 арифметические операции :)
в турбо паскале нет оператора возведения в степень.
00 — это неопределённость, так что о «самом правильном ответе» говорить не приходится.
0^0 = 1, это очень даже определённость. Попробуйте любой калькулятор, если сомневаетесь.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
используя только арифметические операции возвести в произвольную степень не получится
Ну какбы только так :)
x^a = exp(a*ln(x))

Дурацкий язык :P
Экспонента и логарифм - это не арифметические операции, извините:-)
UFO just landed and posted this here
И логарифм от нуля взять не получиться.
Возможно такое решение и имелось ввиду авторами задачки, но тут все-таки неявно используется округление.
Округления тут нет.
Это форматирование вывода.
мож так? вроде и проще и быстрее..

abs(sgn(n))
UFO just landed and posted this here
Я думаю, что в знаковых числах Ваша задача решения вообще не имеет, если не вводить ограничение на диапазон значений чисел.
Если же для промежуточной операции (для деления) можно использовать беззнаковое число, то есть как минимум 2 решения:
cardinal(n) / (cardinal(n / 2) + 1)
и:
1 - cardinal(n - 1) / cardinal(-1)
Без этого на максимально возможном диапазоне я думаю будет работать:
1 - ((n + 1) / ((n + 1) + n))
Арифметические операции - это только сложение, вычитание, умножение и деление
http://en.wikipedia.org/wiki/Arithmetic

Никаких div, abs, возведений в степень, сигнумов и прочих синусов :-)
The traditional arithmetic operations are addition, subtraction, multiplication and division, although more advanced operations (such as manipulations of percentages, square root, exponentiation, and logarithmic functions) are also sometimes included in this subject.

так что пока четко не определено что включать в арифметические операции, правильное решение будет выделить тяжело. автор, просьба дать комментарии по этому поводу.
Осмелюсь заметить что задача для поступления на курс "Первые шаги в программировании" весьма и весьма странная.
Если конечно цель не состоит в том чтобы составить у абитуриентов представление о программировании как о процессе решения бессмысленных головоломок.
UFO just landed and posted this here
long x = 1;
x = x * x;
while (x / 2 != 0) {
    x = x /2;
}
System.out.println(x);
Лучше бы искали оптимальный вариант.
если / есть целочисленное деление без знака, то хороший вариант: (n
[хабра не хочет кушать <]Лучше бы искали оптимальный вариант.
если / есть целочисленное деление без знака, то хороший вариант: (n << 1) / (n++)
Примерное время выполнения:
/ - 35 тактов
<< - 2 такта
++ - 1 такт
Итог 38 тактов
Кто меньше? :)
UFO just landed and posted this here
Микропроцессор MIPS R10000 (http://www.osp.ru/os/1995/06/178765/)
Ваш вариант на отрицательных числах (или больших положительных: 0x80000000+) накроется.
Работают: n / ((n / 2) + 1) и 1 - (n - 1) / -1 (деление беззнаковое).
Задача не имеет решений, если использовать только операции сложения и умножения (деление и вычитание - это то же самое).
Небольшое доказательство.
В конце любой функции, какой бы она сложной ни была, будет выполнено одно последнее арифметическое действие. Операндами этой последней операции будут 2 числа, которые как-то зависят от n. Неважно, как, будем считать, что это две функции f1(n) и f2(n), для простоты ф1 и ф2.
Если последнее действие умножение, то получаем, что ф1*ф2 = 0 при n=0, ф1*ф2 = 1 при n=1. Чтобы оба уравнения имели смысл, рассматриваем как систему, в итоге получается, что ф1=1/ф2. При этом, чтобы не было ошибки, ф2 не равно нулю, получаем, что ф1 тоже не равно нулю, ну тогда и последнее действие никогда не будет давать в результате ноль.
Если последнее действие сложение, то в итоге получаем систему ф1+ф2=0 и ф1+ф2=1. Получаем ф1=1/2, ф2=-1/2. В результате последняя операция вашей функции всегда будет давать 0.

Я вижу, что никто уже и так не мучается, но написал доказательство, чтоб уж точно никто не мучался :)
(n * n * 2) div (n * n + 1)

Учитывались арифметические операции div и умножение.
Вроде все.
Дружище, будет ли опубликован правильный ответ?
Я его сам не знаю, поэтому и написал здесь.
Так как мы используем паскаль, то директива {$I-} означает временное отключение контроля
(хабр скукожил каммент, продолжение)
ошибок ввода-вывода. Так что n/n при n=0 напишет ноль, а не ошибку.
Деление на ноль, это не ошибка ввода-вывода.
Хотя признаюсь эта мысль тоже приходила мне в голову.
Низя. Там была методичка для поступающих, в которой ничерта про это не было сказано.
На паскале лень проверять, но на Си сделал следующим образом:

int n = 12345; // введенное целое число
double e = 0.0000000000000001; // число, меньшее машинного эпсилон
double z = e/(e+n); // 1.0 либо число меньшее машинного эпсилон
int res = 1 + z - 1; // 1 если n=0, иначе 0

Правда в последней строчке неявно используется преобразование типов, но только для того чтобы из 1.0 или 0.0 сделать 1 или 0 соответственно.
Также результат возможно будет зависеть от оптимизатора.
Надеюсь никого не удивляет то, что хотя e != 0, выражение 1.0 + e == 1.0 возвращает true...
Sign up to leave a comment.

Articles