zoukankan      html  css  js  c++  java
  • [代码]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;
    }
  • 相关阅读:
    一个可以用的Lua的Class函数
    写一个可以用的Lua打印Table的函数
    关于C#的接口的碎碎念
    C#中接口是值类型还是引用类型?
    Effective C++笔记_条款31将文件间的编译依存关系降至最低
    Effective C++ 阅读笔记_条款27 尽量少做转型动作
    Flask--开发全套
    python之元类
    Django之模板层
    go打开文件
  • 原文地址:https://www.cnblogs.com/jffifa/p/2698646.html
Copyright © 2011-2022 走看看