I need to calculate the value for the following function:
$$f(n) = -1 + 2 - 3 + ... + -1^n$$
The time limit to calculate a given value of \$n\$ is less than 1 second. My approach does not meet that requirement at large sizes, for example \$f(1000000000)\$.
My code:
program A486;
uses wincrt, sysutils;
var
n: LongInt;
function f(n : LongInt): LongInt;
var
i : LongInt;
//Result : LongInt;
begin
Result:= 0;
for i:= 1 to n do
if i mod 2 = 0 then
Result += i
else
Result -= i;
//f:= Result;
end;
begin
readln(n);
writeln(f(n));
//readkey()
end.
Is there a better way I can do this?
3 Answers 3
Seems trivial. Pair them, each pair is worth -1.
f(1000) = 1 - 2 + 3 - 4 + ... + 999 - 1000
= (1 - 2) + (3 - 4) + ... + (999 - 1000)
= -1 -1 + ... + -1
= -500
Odd n left as exercise for the reader.
(I wrote this when the question title still said "1 − 2 + 3 − 4 + · · ·", can't be bothered to switch all signs now.)
According to the help of Mr Andreas, i have come up with this code, which was helpful, but it gave a runtime error, in this test : 1000000000000000
, I have to disapprove the answer as it wasn't the best performance. But i still greatly thank you for your attention.
code :
program A486;
uses wincrt, sysutils;
var
n: LongInt;
function f(n : LongInt): LongInt;
var
{Result,} SumOdd, SumEven : LongInt;
begin
Result:=0; SumOdd:=0; SumEven:=0;
if n mod 2 = 0 then
begin
SumOdd:=( n*(n div 2) ) div 2;
SumEven:=((2+n)*(n div 2) ) div 2;
Result:= SumOdd - SumEven;
end else
begin
SumOdd:=( (n+1)*(n div 2 + 1) ) div 2;
SumEven:=((n+1)*(n div 2) ) div 2;
Result:= SumOdd - SumEven;
end;
//f:= Result;
end;
begin
readln(n);
writeln(f(n));
//readkey()
end.
As far as we discussed it, this is the most efficient answer found:
program A486;
uses wincrt, sysutils;
var
n: LongInt;
function f(n : LongInt): LongInt;
//var
//Result : LongInt;
begin
Result:=0;
if n mod 2 = 0 then
Result:= n div 2
else
Result:= (n div 2) - n;
//f:= Result;
end;
begin
readln(n);
writeln(f(n));
//readkey()
end.
thanks for everyone helped!
-
1\$\begingroup\$ It might not speed up your code but you could rewrite that whole if statement as -1^(n % 2) * ceiling(n / 2) The pattern to your problem is that results go -1, 1, -2, 2, -3, 3, ... -roundUp(n / 2), roudUp(n / 2). Odd numbers mod 2 are always 1 and even numbers mod 2 are 0 so -1^(n mod 2) will keep alternating the negative sign for you and roundUp(n / 2) gives you the int value at each step \$\endgroup\$Coupcoup– Coupcoup2020年09月11日 22:31:01 +00:00Commented Sep 11, 2020 at 22:31
-
1\$\begingroup\$ how about
Result := (n shr 1) - n * (n and 1);
? \$\endgroup\$W. Chang– W. Chang2020年09月22日 17:41:19 +00:00Commented Sep 22, 2020 at 17:41
Explore related questions
See similar questions with these tags.