URAL 1849|Rabbit Hunt 2|计算几何|二分|Set

21 篇文章 0 订阅
20 篇文章 0 订阅

给出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 = 10005;
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[25][25][N];
bool cmp(const Data &a, const Data &b) {
    Data c = a - b;
    if (base ^ c) return (base ^ c) > 0;
    else return base * c < 0;
}
int main() {
    int n, t, ans, id, i, j, k;
    while (scanf("%d", &n) != EOF) {
        rep(i,0,n) p[i].in();
        scanf("%d", &t);
        o.in(); v.in(); x.in(); y.in(); vx.in(); vy.in();

        FOR(i,-10,10) FOR(j,-10,10) if (i || j) {
            base = Data(i, j);
            sort(p, p + n, cmp);
            rep(k,0,n) tab[i + 10][j + 10][k] = p[k];
        }

        ans = id = 0;
        FOR(i,1,t) {
            base = v;
            Data *d = tab[v.x + 10][v.y + 10];
            int L = lower_bound(d, d + n, o, cmp) - d;
            int R = lower_bound(d, d + n, o + v * 100000, cmp) - d;
            int w = R - L;
            if (w >= ans) ans = w, id = i;

            o.x = (x.x * (o.x + 10000) + x.y) % 20001 - 10000;
            o.y = (y.x * (o.y + 10000) + y.y) % 20001 - 10000;
            v.x = (vx.x * (v.x + 10) + vx.y) % 21 - 10;
            v.y = (vy.x * (v.y + 10) + vy.y) % 21 - 10;
        }
        printf("%d %d\n", id, ans);
    }
    return 0;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值