We have two rows.
There are a dots on the top
row and b dots on the
bottom row. We draw line segments connecting every dot on the top row with
every dot on the bottom row. The dots are arranged in such a way that the
number of internal intersections among the line segments is maximized. To
achieve this goal, we must not allow more than two segments to intersect in a
point. The intersection points on the top row and the bottom are not included
in our count; we can allow more than two segments to intersect on those two
rows. Given the value of a and b, your task is to compute P(a, b), the number of intersections in between the two rows. For
example, in the following figure a = 2 and b = 3. This figure illustrates
that P(2, 3) = 3.
Input. Each line contains two positive integers a (0 < a
≤ 20000) and b (0 < b ≤ 20000). Input is terminated by a
line where both a and b are zero. This case should not be
processed. You will need to process at most 1200 sets of inputs.
Output. For each test
case print in a line its serial number followed by the value of P(a, b). Look at the sample output for details. You can assume that the
output for the test cases will fit in 64-bit signed integers.
Sample
input |
Sample
output |
2 2 2 3 3 3
0 0 |
Case 1: 1 Case 2: 3 Case 3: 9 |
combinatorics
Let f(a, b)
be the required
number of intersection points. Obviously, f(1, b) = 0, since for a = 1 no two segments intersect.
Consider the
general case. Let x1, x2, …, xa be points
on the first line, y1,
y2, …, yb be points on the second line. Connect point x1 with poinys y1, y2,
…, yb. There will be no intersection points on the segment x1y1.
The segment x1y2 will contain
the points of intersection with the segments y1x2, y1x3, …, y1xa
(a – 1 points in total). The segment x1yj will contain
the points of intersection with the segments yixk,
where i < j,
2 £ k £ a ( (j
– 1) * (a – 1) points in total). The number of intersection points
that lie on the segments outgoing from x1 is (0 + 1 + 2 + …
+ (b – 1)) * (a – 1) = b * (b – 1) / 2 * (a
– 1).
So, out of f(a, b) points b * (b – 1) / 2 * (a – 1) points lie on segments outgoing from x1,
and the rest of the points lie on segments with ends at x2, …, xa.
We have a recurrent relation:
f(a, b)
= b * (b – 1) / 2 * (a – 1) + f(a – 1, b)
Expanding it, we
get:
f(a, b)
= b * (b – 1) / 2 * (a – 1) + f(a – 1, b) =
b * (b –
1) / 2 * (a – 1) + b * (b – 1) / 2 * (a – 2) + f
(a – 2, b) = ... =
b * (b –
1) / 2 * (a – 1) + b * (b – 1) / 2 * (a – 2) + ... + b * (b – 1) / 2 * 1 =
b * (b –
1) / 2 * ( (a – 1) +
(a – 2) + ... + 1) =
b * (b –
1) / 2 * a * (a – 1) / 2
Thus, the
maximum number of intersection points is
*
Example
Consider the
second test
case, where a = 2, b = 3. The
maximum possible number of intersection points among the segments is 3 and this is shown in the
figure:
Read the input
data and for each test cae calculate the result according to the above formula. Given
the constraints on a and b, there will be no overflow in
multiplication if calculations are performed in a 64-bit integer type.
cs = 1;
while(scanf("%lld
%lld",&a,&b), a + b > 0)
{
res = a * (a - 1) * b * (b - 1) / 4;
printf("Case
%d: %lld\n",cs++,res);
}
Java
realization
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Scanner con = new
Scanner(System.in);
int cs = 1;
while(true)
{
long a = con.nextLong();
long b = con.nextLong();
if (a + b == 0) break;
long res = a * (a - 1) * b * (b - 1) / 4;
System.out.println("Case " + cs++ + ": " + res);
}
con.close();
}
}