給出N個點和一些射線,求哪條射線穿過的點數最多。
發現射線的方向向量隻有20*20種,我們可以為每種方向的射線,改變點的組織方式,這樣查詢時就可以快速出解了。
方法1
考慮這麼一種排序方式:對于每個基準向量,如果一些點在同一條直線上而且平行于基準向量,就按照其方向排列,其他在這條直線左側的,排在這些點之前,否則排在之後。
那麼對于每個詢問就很簡單了,二分這個序列即可。
方法2
另外一種做法是,對于每個基準向量,以原點為中心旋轉所有的點和基準向量,使得基準向量平行坐标軸,那麼這些點的新坐标以及射線的起點都知道了,答案也顯而易見了。需要set維護。
#include <cstdio>
#include <algorithm>
using namespace std;
#define FOR(i,j,k) for(i=j;i<=k;++i)
#define rep(i,j,k) for(i=j;i<k;++i)
const int N = ;
struct Data {
int x, y;
Data() { }
Data(int a, int b) : x(a), y(b) { }
Data operator+ (const Data &b) const { return Data(x + b.x, y + b.y); }
Data operator- (const Data &b) const { return Data(x - b.x, y - b.y); }
Data operator* (int b) const { return Data(b * x, b * y); }
int operator^ (const Data &b) const { return x * b.y - y * b.x; }
int operator* (const Data &b) const { return x * b.x + y * b.y; }
void in() { scanf("%d%d", &x, &y); }
} p[N], base, o, v, x, y, vx, vy, tab[][][N];
bool cmp(const Data &a, const Data &b) {
Data c = a - b;
if (base ^ c) return (base ^ c) > ;
else return base * c < ;
}
int main() {
int n, t, ans, id, i, j, k;
while (scanf("%d", &n) != EOF) {
rep(i,,n) p[i].in();
scanf("%d", &t);
o.in(); v.in(); x.in(); y.in(); vx.in(); vy.in();
FOR(i,-,) FOR(j,-,) if (i || j) {
base = Data(i, j);
sort(p, p + n, cmp);
rep(k,,n) tab[i + ][j + ][k] = p[k];
}
ans = id = ;
FOR(i,,t) {
base = v;
Data *d = tab[v.x + ][v.y + ];
int L = lower_bound(d, d + n, o, cmp) - d;
int R = lower_bound(d, d + n, o + v * , cmp) - d;
int w = R - L;
if (w >= ans) ans = w, id = i;
o.x = (x.x * (o.x + ) + x.y) % - ;
o.y = (y.x * (o.y + ) + y.y) % - ;
v.x = (vx.x * (v.x + ) + vx.y) % - ;
v.y = (vy.x * (v.y + ) + vy.y) % - ;
}
printf("%d %d\n", id, ans);
}
return ;
}
Rabbit Hunt 2
Time Limit: 4000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u
Description
A good hunter kills two rabbits with one shot. But you need to kill the maximal possible number of rabbits with one shot to become the best hunter in the world. The program Rabbit Hunt 2 might be quite helpful. This program treats all rabbits as points on a plane. It reads coordinates of n rabbits from the input, generates q different shooting propositions and chooses the one which leads to killing the maximal number of rabbits. A shooting proposition is defined by coordinates of the hunter and the direction of shooting. The shot kills all the rabbits lying on the corresponding ray including the rabbit situated at the same point as the hunter.
A proposition generator uses numbers ax, bx, ay, by, avx, bvx, avy, bvy. Coordinates of the hunter in the first proposition is ( x1, y1), and a direction of shooting is ( vx1, vy1). Coordinates and direction in the i-th proposition ( i > 1) are calculated using these formulas:
Problem illustration
Unfortunately, the program Rabbit Hunt 2 doesn’t exist yet. Your goal is to create it.
Input
The first line contains a number of rabbis n (1 ≤ n ≤ 10 000). The next n lines contain the coordinates of rabbits. Coordinates are integers not exceeding 10 000 in their absolute value. No two rabbits are situated at the same point. The next line contains a number of shooting propositions q (1 ≤ q ≤ 10 6). The next line contains integers x1, y1, vx1, vy1 (−10 000 ≤ x1, y1 ≤ 10 000; −10 ≤ vx1, vy1 ≤ 10) . The last line contains non-negative integers ax, bx, ay, by, avx, bvx, avy, bvy. All these numbers don’t exceed 10 5. It is guaranteed that the direction of shooting is a non-zero vector for all q propositions. All numbers in lines are separated by single spaces.
Output
Output the number of proposition resulting in the maximal quantity of killed rabbits and this quantity. If there are several such propositions, output the one with the maximal number.
Sample
input
4
0 0
2 0
3 0
2 2
3
-1 -1 1 0
1 0 1 1 1 0 1 0
output
2 3
Source
Problem Author: Alex Samsonov
Problem Source: Ural SU Contest. Petrozavodsk Summer Session, August 2010