[代码]HDU 4400 Mines

Abstract

HDU 4400 Mines

x坐标法……

 

Body

Source

http://acm.hdu.edu.cn/showproblem.php?pid=4400

Description

给定N个点的平面点集(可能有重点),每个点向与其曼哈顿距离不超过d[i]的点连边。每次询问拿走某个点及其传递闭包,问总共拿走多少个点。

Solution

其实是很没节操的题,暴力做就是了……不过今天卡得眼泪汪汪所以就没做到。

把x坐标离散化后每个点塞到相应x坐标的multiset里。查询时就二分一下x坐标的范围,然后对范围内的每个multiset再二分y坐标。之后就是简单的标记和BFS了……

正解的话,我猜是kd树,或者是树套树?

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;

struct snode {
    int y, id;
    snode() {}
    snode(int a, int b): y(a), id(b) {}
    bool operator<(const snode &rhs) const {
        return y<rhs.y;
    }
};

typedef multiset<snode>::iterator itr;

int N, M, X;
int hash[111111];
int x[111111], y[111111], d[111111];
bool vis[111111];
multiset<snode> p[111111];
queue<int> q;

int main() {
    int i, j, k;
    int t = 0;
    while (cin>>N, N) {
        for (i = 0; i < N; ++i) {
            scanf("%d%d%d", x+i, y+i, d+i);
            hash[i] = x[i];
        }
        sort(hash, hash+N);
        X = unique(hash, hash+N)-hash;
        for (i = 0; i < X; ++i)
            p[i].clear();
        for (i = 0; i < N; ++i) {
            j = lower_bound(hash, hash+X, x[i])-hash;
            p[j].insert(snode(y[i], i));
        }
        memset(vis, 0, sizeof vis);
        cin>>M;
        printf("Case #%d:\n", ++t);
        while (M--) {
            scanf("%d", &k);
            k--;
            if (vis[k]) {
                puts("0");
                continue;
            }
            vis[k] = 1;
            q.push(k);
            int l, r, dy;
            int cnt = 0;
            itr yl, yr;
            while (!q.empty()) {
                ++cnt;
                k = q.front();
                q.pop();
                l = lower_bound(hash, hash+X, x[k]-d[k])-hash;
                r = upper_bound(hash, hash+X, x[k]+d[k])-hash;
                for (i = l; i < r; ++i) {
                    dy = d[k]-abs(x[k]-hash[i]);
                    yl = p[i].lower_bound(snode(y[k]-dy, 0));
                    yr = p[i].upper_bound(snode(y[k]+dy, 0));
                    for (itr it = yl; it != yr; ++it)
                        if (!vis[it->id]) {
                            vis[it->id] = 1;
                            q.push(it->id);
                        }
                    p[i].erase(yl, yr);
                }
            }
            printf("%d\n", cnt);
        }
    }
    return 0;
}
posted @ 2012-09-23 02:09  杂鱼  阅读(577)  评论(0编辑  收藏  举报