Всем привет. Решаю несложную геометрию. Решаю вот как: считываю xi, yi, составляю уравнение прямой которое проходит через x0, y0, xi, yi пользуясь формулой (x — x1) / (x2 — x1) = (y — y1) / (y2 — y1). И добавляю уравнение в множество (std::set). И потом просто вывожу размер множества. Коэффициенты прямой храню в виде пар чисел которые представляют несократимую дробь. К сожалению на 8 тесте получаю WA. Где может быть баг? 16591043
Легче:
Подумайте, что различает все ваши прямые, когда вы строите их по "школьному" уравнению прямой.
Как я понимаю, точка пересечения с OX, OY? З.Ы Не судите строго, я еще нуб.
K
Я вот как решил:
Прямую задает однозначно направляющий вектор и точка через которую она проходит. Вычисляем координаты направляющего вектора в double: vx=(x-x0)/mod, vy=(y-y0)/mod где mod=sqrt( sqr(x-x0) + sqr(y-y0) ). Также получаем координаты того же вектора в обратном направлении vx'=-vx, vy'=-vy. Далее слегка загвоздка выходит, т.к вставляя эти две пары координат в set < pair<double,double> > точно выйдет погрешность со сравнением. Поэтому вставляем в pair <int,int> эти пары помноженные на, скажем 1000000000. На ограничениях этой задачи погрешность не случится. И да, ответом будет размер set'a деленный на 2.
Я не понял, зачем при запоминании прямой хранилась вторая пара.
Но если её убрать, это решение проходит.
Кстати, хороший тест для такой задачи — все точки грида в некоторой окрестности, например:
И руками легко ответ посчитать (8), и ловит баг в исходном решении.
Кстати, вот пожалуй лучшее решение этой задачи за O(N log N) 9838096. Очень просто, странно что я не подумал об этом.
Ну так если в вашем решении убрать
b
изk x + b
и оставить толькоk
, разрешив ему быть нулём, как раз и получается то же самое. Даже короче, потому чтоgcd
сразу правильного знака. Числоb
не нужно, поскольку все наши прямые проходят через одну точку.