10790. Сколько точек пересечения?

 

Имеются две параллельные прямые. На одной из них выбрано a точек, на другой – b точек. Любые две точки с разных прямых соединены отрезком. Точки на прямых выбраны так, что количество точек пересечения образованных отрезков максимально. Вычислить это количество точек пересечения.

 

Вход. Каждая входная строка содержит два числа a и b (0 £ a £ 20000, 0 £ b £ 20000). Обработка данных заканчивается, когда a = b = 0.

 

Выход. Для каждого теста вывести в отдельной строке его номер и максимально возможное количество точек пересечения отрезков. Результат каждого теста помещается в 64 – битовое число без знака.

 

Пример входа

Пример выхода

2 2

2 3

3 3

0 0

Case 1: 1

Case 2: 3

Case 3: 9

 

 

РЕШЕНИЕ

геометрия + комбинаторный подсчет

 

Анализ алгоритма

Обозначим через f(a, b) искомое количество точек пересечения. Очевидно, что f(1, b) = 0, так как при a = 1 никакие два отрезка не пересекаются:

Рассмотрим общий случай. Пусть x1, x2, …, xa – точки на первой прямой,  y1, y2, …, yb – точки на второй прямой. Соединим точку x1 с точками y1, y2, …, yb. На отрезке x1y1 точек пересечения не будет. На отрезке x1y2 будут лежать точки пересечения с отрезками y1x2, y1x3, …, y1xa (всего a – 1 точек). На отрезке x1yj будут лежать точки пересечения с отрезками yixk, где i < j, 2 £ k £ a (всего (j – 1) * (a – 1) точек). Количество точек пересечения, которые лежат на отрезках исходящих из x1, равно (0 + 1 + 2 + … + (b – 1)) * (a – 1) = b * (b – 1) / 2 * (a – 1).

Итак, из f(a, b) точек b * (b – 1) / 2 * (a – 1) точек лежат на отрезках исходящих из x1, а остальные точки лежат на отрезках с концами в x2, …, xa. Имеем рекуррентное соотношение:

f(a, b) = b * (b – 1) / 2 * (a – 1) + f(a – 1, b)

Развернув его, получим:

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 * (a – 1) / 2

Таким образом, максимальное количество точек пересечения равно

 *

 

Пример

Рассмотрим второй тест, для которого a = 2, b = 3. Максимально возможное количество точек пересечения отрезком равно 3 и показано на рисунке:

 

 

 

 

 

 


Реализация алгоритма

Читаем входные данные и для каждого теста вычисляем результат по выше приведенной формуле. При заданных ограничениях на a и b в умножении переполнения не будет, если вычисления проводить в 64-битовом целочисленном типе.

 

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 реализация

 

import java.io.*;

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);

    }

  }

}