Самый похожий профиль продаж мороженого

тема: Расстояния и kNN · уровень: средний

Условие

В киоске с мороженым для каждого дня записывают продажи по категориям: пломбир, фруктовый лёд, рожки и другим. Один профиль является текущим днём, а остальные профили относятся к прошлым дням.

Некоторые значения ещё не внесены в журнал. Такое значение обозначается числом -1 и не участвует в сравнении. Требуется найти номер прошлого дня, профиль которого наиболее похож на текущий по косинусной близости.

Для текущего профиля x и профиля прошлого дня y рассматриваются только категории, в которых оба значения не равны -1. Пусть множество номеров таких категорий равно I. Косинусная близость определяется формулой

S(x, y) = (Σ по i из I x[i] · y[i]) / (sqrt(Σ по i из I x[i]^2) · sqrt(Σ по i из I y[i]^2)).

Гарантируется, что для каждого прошлого дня множество I не пусто и обе суммы квадратов в знаменателе положительны. Если наибольшая косинусная близость достигается у нескольких прошлых дней, выводится наименьший номер среди них.

Формат ввода

В первой строке даны два целых числа n и m: количество прошлых дней и количество категорий мороженого.

Во второй строке записаны m целых чисел — профиль продаж текущего дня.

В следующих n строках записаны профили прошлых дней в порядке их номеров от 1 до n. В каждой строке содержится m целых чисел.

Формат вывода

Выведите одно целое число — номер прошлого дня с наибольшей косинусной близостью к текущему профилю.

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

Ограничения

1 ≤ n ≤ 2000.

1 ≤ m ≤ 30.

Каждое значение продаж — целое число от 0 до 10000, либо -1, обозначающее пропуск.

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

Решить задачу с автопроверкой на Python →

Куда дальше