11311. Расстояние до заданной точки

 

Это интерактивная задача

На плоскости отмечены целые точки с координатами, не превосходящими 106. Движение разрешено по линиям, параллельным осям координат, поэтому расстояние между двумя точками с координатами x1, y1 и x2, y2 вычисляется как |x1 x2| + |y1 y2|.

Имеется неизвестная точка A. Вы можете за один запрос узнать расстояние от выбранной точки до точки A. Ваша задача найти координаты A используя два запроса.

 

Протокол взаимодействия

Взаимодействие запускается Вашей программой. Вы можете задавать вопросы в формате x y” – узнать расстояние от отмеченной точки с координатами x, y до точки A (-106 x, y 106, x и y целые числа).

Если Вы готовы вывести ответ, то используйте следующий формат: x y(x и y координаты точки A), после чего происходит выход из программы. Это действие не считается запросом.

 

Примечание

Для корректного взаимодействия выводите конец строки после каждого запроса и после ответа, а также очищайте буфер вывода соответствующими функциями используемого языка программирования:

·        cout.flush() или fflush(stdout) для C/C++;

·        stdout.flush() для Python;

·        смотрите документацию для других языков.

 

Пример входа

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

 

1

 

0

? 0 0

 

? 1 0

 

! 1 0

 

 

РЕШЕНИЕ

математика

 

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

Пусть INF = 106. Сделаем два запроса в точках X(-INF, -INF) и Y(INF, -INF).

Пусть O(x, y) – координаты искомой точки.

Пусть d(O, X) = a, d(O, Y) = b. Через d(O, X) обозначено расстояние между точками O и X.

 

 

Имеем систему: , откуда a + b = k + m + 2l. Учитывая что k + m = 2 * INF, имеем: a + b = 2 * INF + 2l. Отсюда l = (a + b – 2 * INF) / 2.

Зная значение l, можно найти y координату искомой точки: y = – INF + l.

Поскольку a = k + l, то k = al.

Абсцисса искомой точки равна x = – INF + k = – INF + al.

Таким образом искомая точка имеет координаты O(– INF + al, – INF + l).

 

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

Определим константу INF = 106.

 

#define INF 1000000

 

Функция ask возвращает расстояние res от отмеченной точки до точки (x, y).

 

int ask(int x, int y)

{

 

Выводим запрос – узнать расстояние от отмеченной точки до (x, y).

 

  printf("? %d %d\n", x, y);

 

Очищаем буфер вывода для корректного взаимодействия программы и интерактора.

 

  fflush(stdout);

  int res;

 

Читаем и возвращаем ответ интерактора – расстояние от отмеченной точки до (x, y).

 

  scanf("%d", &res);

  return res;

}

 

Основная часть программы. Узнаем расстояния a = d(O, X) и b = d(O, Y), где O(x, y) – искомая точка, X(-INF, -INF), Y(INF, -INF).

 

int a = ask(-INF, -INF);

int b = ask(INF, -INF);

 

Находим длину отрезка l.

 

int l = (a + b - 2 * INF) / 2;

 

Вычисляем координаты (x, y) искомой точки.

 

int x = -INF + a - l;

int y = -INF + l;

 

Выводим координаты искомой точки и чистим буфер вывода.

 

printf("! %d %d\n", x, y);

fflush(stdout);

 

Ниже приводим полную программу.

 

#include <stdio.h>

#define INF 1000000

 

int ask(int x, int y)

{

  printf("? %d %d\n", x, y);

  fflush(stdout);

  int res;

  scanf("%d", &res);

  return res;

}

 

int main()

{

  int a = ask(-INF, -INF);

  int b = ask(INF, -INF);

 

  int l = (a + b - 2 * INF) / 2;

 

  int x = -INF + a - l;

  int y = -INF + l;

  printf("! %d %d\n", x, y);

  fflush(stdout);

 

  return 0;

}