I wanna print how many triangles exist having the perimeter of n.(with integer sides). Actually the formula I used is here. T(n): n=even --> n^2/48 | n=odd --> (n 3)^2/48. and here is my code:
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
double m = 0;
if(n%2==0)
{
m =Math.Round( n * n / 48.0);
}
else
{
m = Math.Round((n 3) * (n 3) / 48.0);
}
Console.Write(m);
}
It actually gives me half of the score.
CodePudding user response:
It turned out the problem was the asker was supposed to handle values n
up to 1_000_000. But for such inputs n * n
which is done as integer multiplication, overflows silently and produces an unexpected result.
(Curiously, for these cases it could have worked to switch to double
earlier, like saying n * (n / 48.0)
or (double)n * n / 48.0
instead of n * n / 48.0
.)
You can use a syntax like checked { /* statements here */}
or (inside an expression) checked(n * n)
to get an exception rather than a silent loss of significant bits that the fixed-width integer type cannot hold.
The asker fixed it by switching to long
:
static void Main(string[] args)
{
long n = long.Parse(Console.ReadLine());
double m;
if (n % 2 == 0)
{
m = Math.Round(n * n / 48.0);
}
else
{
m = Math.Round((n 3) * (n 3) / 48.0);
}
Console.Write(m);
}
If you have access to System.Numerics, you can write a solution that works for even bigger inputs:
static void Main(string[] args)
{
BigInteger n = BigInteger.Parse(Console.ReadLine());
BigInteger m;
if (n % 2 == 0)
{
m = (n * n 24) / 48;
}
else
{
m = ((n 3) * (n 3) 24) / 48;
}
Console.Write(m);
}
where we use integer division /
, and the trick of adding half the denominator to the numerator ensures correct rounding to nearest.