var
x,y,z: double;
begin
readln(x);
z:= Frac(Abs(x)/6)*6;
if z<1then y:= 1-z
elseif z<2then y:= 0elseif z<3then y:= 2-z
elseif z<4then y:= z-4elseif z<5then y:= 0else y:= z-5;
writeln(y:8:3);
readln
end.
Или вот так:
const
a: array [0..5] of double = ( 1, 0, 2,-4, 0,-5);
b: array [0..5] of double = (-1, 0,-1, 1, 0, 1);
var
x,y,z: double;
begin
readln(x);
z:= Frac(Abs(x)/6)*6;
y:= a[Trunc(z)]+b[Trunc(z)]*z;
writeln(y:8:3);
readln
end.
Lapp
14.04.2011 7:43
И еще один способ до кучи ))
var
x,y: double;
begin
readln(x);
y:= Round(Cos(Trunc(x)*Pi/3)*0.9)+(Round(Cos((Trunc(x)+1)*Pi/3)*0.9)-Round(Cos(Trunc(x)*Pi/3)*0.9))*Frac(x);
writeln(y:8:3);
readln
end.
Но это в предположении, что x>=0 (как, сосбно, и есть на рисунке). Если нужна отрицательная полуось, то нужно просто везде заменить x на Abs(x) (либо сделать x:=Abs(x) сразу после ввода).
Lapp
14.04.2011 9:08
Что-то не отпускает меня эта задача.. Вот еще один способ Тут я для разнообразия выделил повторяющиеся вычисления в функцию - в третьем способе это тоже напрашивается. Способ вообще аналогичен третьему, но там периодичность достигалась косинусом, а тут - простым делением на 6 (как в первых двух).
var
x,y: double;
function f(x: double): double;
begin
f:= Round(Abs(Frac(x/6)-0.5)*4-1)
end;
begin
readln(x);
x:= Abs(x);
y:= f(Trunc(x)) + (f(Trunc(x+1))-f(Trunc(x)))*Frac(x);
writeln(y:8:3);
readln
end.
Оговорка про знак x та же, что и в предыдущем методе, только тут я уже вставил Abs(x).
Интересно - этот способ окажется последним? ))
Добавлено через 17 мин. Пятый способ является модификацией первого, основанной на симметричности периода..
var
x,y,z: double;
begin
readln(x);
z:= Abs(Frac(Abs(x)/6)*6-3);
if z<1then y:= z-1elseif z<2then y:= 0else y:= z-2;
writeln(y:8:3);
readln
end.
люди, спасите, пропадаю.. как мне эту дрянь из головы выкинуть??.. "режьте, братцы, режьте, режьте осторожно.." (С)
Lapp
14.04.2011 10:13
Шестой способ центрирован на середины горизонтальных отрезков. Вся область разбивается на куски длиной 3 (с центрами в означенных точках). На каждом таком куске наша функция оказывается нечетной, при этом знак функции чередуется от куска к куску:
var
x,y: double;
function f(x: double): double;
begin
f:= Abs(Frac(x/3)-0.5)
end;
begin
readln(x);
x:= Abs(x);
if f(x)<1/6then y:=0else y:= (f(x)*3-0.5)*(1-Trunc((x+1.5)/3) mod2*2);
writeln(y:8:3);
readln
end.
а что? я ничего.. я тихий, смирный.. сижу - примус починяю (С).. не надо меня в Кащенко.. можно я погрызу ваши тапки? ну что вам, жалко что ли.. тяф!.. тяфф!..
Lapp
14.04.2011 11:25
Еще одна модификация первого способа, но в другом смысле (нежели чем способ 5). Просто замена вложенных if на case, что позволяет немало сократить код:
var
x,y,z: double;
begin
readln(x);
z:= Frac(Abs(x)/6)*6;
case Trunc(z) of0: y:= 1-z;
1,4: y:= 0;
2: y:= 2-z;
3: y:= z-4;
else y:= z-5;
end;
writeln(y:8:3);
readln
end.
ляляля... ляляля.. ... Таак, интересно.. кажется, этот способ может быть продолжен.. кто нибудь дома? тук-тук!
Добавлено через 15 мин.
Цитата(Lapp @ 14.04.2011 8:25)
Таак, интересно.. кажется, этот способ может быть продолжен..
Ага, так и вышло )). В моей классификации он назвался 7a, но тут пускай уж будет восьмой:
var
x,y,z: double;
i: integer;
begin
readln(x);
z:= Frac(Abs(x)/6)*6;
i:= Trunc(z);
case i of0,2: y:= i div2+1-z;
1,4: y:= 0;
else y:= z-4-(i-3) div2;
end;
writeln(y:8:3);
readln
end.
Я тут ввел еще одну (целую) переменную - чисто для удобства (и небольшой экономии вычислений).
чуть помедленее, кони, чуть помедленнее.. не указчики вам кнут и плеть!.. (С)
а вы не слышали - какая погода на северо-востоке кратера Коперника в эти выходные?.. надо бы смотаться, развеяться немного Кто со мной? на обратную сторону Луны не приглашать, там всегда дождь..