Triangle Counting time limit: +Ms | Memory Limit:65535KB Difficulty:3
-
-
Describe
-
You are given n rods of length 1, 2 ..., N. You have the pick any 3 of them and build a triangle. How many distinct triangles can do? Note that, the triangles would be considered different if they has at least 1 pair of arms with different length.
-
-
Input
-
The input for each case would have
-
a single positive integer n (1<=n<=1000000). The end of input would be indicated by a case with n<1. This case is should not being processed.
-
-
Output
-
-
for the all test case, print the number of distinct triangles your can make.
-
-
Sample input
-
-
580
-
-
Sample output
-
-
322
-
-
Source
-
-
UVA
-
Uploaded by
Tc_ Li Yuanhai
Ideas:
The conventional idea is to simulate
But the complexity of the time will be (o^3) the obvious timeout
So we're guessing there must be a pattern, from a mathematical point of view.
Set the longest edge of the triangle to X, (other y,z) a maximum of C (x) triangles
So Y+z>x
X-y<z<x
So when Y=1 is misunderstood 0 y=2 a solution y=3 three solutions .....
0+1+2+3+....+ (x-2)
Total: (x-2) * (x-1)/2
But this is where the y=z is calculated and two times per triangle.
(Y=z situation) y=x/2+1 start (x-1)-(x/2+1) +1=x/2-1 not difficult to find X for odd case is X/2 even case is x/2-1 so→ (tip) (X-1)/2 Avoid parity discussion
So C (x) = ((x-1) (x-2)/2-(x-1)/2)/2
The problem is the number of so F (n) =f (n-1) +c (n) of triangles with the longest side length not exceeding n;
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm>using namespace Std;long long A[1000005];int Main () { int n; a[1]=a[2]=a[3]=0; For (long long i=4;i<1000005;i++) a[i]=a[i-1]+ ((i-1) * (i-2)/2-(i-1)/2)/2; while (~SCANF ("%d", &n) } { if (n<=0) break ; printf ("%lld\n", A[n]);} }
Math: give you length 1~n line segments the longest edge length of the triangle does not exceed the number of your n triangles