HDU 4400 Mines

HDU 同时被 2 个专栏收录
56 篇文章 0 订阅
76 篇文章 0 订阅

题目大意是二维坐标系上有一些炸弹,每个炸弹有x,y坐标和爆炸后波及的范围r,这个r指的是跟自己曼哈顿距离r以内的点

就类似于扫雷那样,一个炸弹爆炸可能引起一片一片的炸弹炸出去

然后有一些询问,问点燃某个炸弹后会有多少个炸弹爆炸 已经炸过的就不算了


应该不难想到是用BFS去找临近的点

我的做法是把横坐标离散化,然后每个横坐标建立一个vector,把相应的y都塞进去

然后每次询问,就bfs, 根据每个炸弹的波及范围,如果炸弹横坐标为x,波及范围为r,那么就去找x-r到x+r坐标的vector

然后在vector里寻找相应范围的y

一个lower_bound和一个upper_bound函数就搞定,然后用erase去除爆炸的点

据说正解应该是KD Tree? 不过我不会那种神奇的数据结构,比赛的时候就试着搞了下STL,没想到直接就过了。也许是数据弱?

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
using namespace std;
const int maxn = 110005;
const int inf = 2000000005;
struct NODE{
    int y, dis;
    NODE(){
    }
    NODE(int _y, int _dis){
        y = _y; dis = _dis;
    }
    bool operator <(const NODE &tmp)const{
        if(y == tmp.y) return dis < tmp.dis;
        return y < tmp.y;
    }
};
struct POINT{
    int x, y, dis;
    POINT() {
    }
    POINT(int _x, int _y, int _dis){
        x = _x;
        y = _y;
        dis = _dis;
    }
}df[maxn], myque[1111111];
int n, m, hash[maxn], num;
vector<NODE>mygraph[maxn];
void init(){
    num = 0;
    for(int i = 0; i < maxn; i++) mygraph[i].clear();
}
void readdata(){
    for(int i = 1; i <= n ; i++){
        scanf("%d%d%d", &df[i].x, &df[i].y, &df[i].dis);
        hash[num++] = df[i].x;
    }
    sort(hash, hash + num);
    num = unique(hash, hash + num) - hash;
    for(int i = 1; i <= n; i++){
        int id = lower_bound(hash, hash + num, df[i].x) - hash;
        mygraph[id].push_back(NODE(df[i].y, df[i].dis));
    }
}
int fuckit(int fuckid){
    int head = 0, tail = 0, ret = 0;
    vector<NODE>::iterator vectoriterator1, vectoriterator2, tmpvectoriterator;
    myque[tail++] = POINT(df[fuckid].x, df[fuckid].y, df[fuckid].dis);
    while(head < tail){
        POINT now = myque[head++];
        int pos1 = lower_bound(hash, hash + num, now.x - now.dis) - hash;
        int pos2 = upper_bound(hash, hash + num, now.x + now.dis) - hash;
        for(; pos1 != pos2; pos1++){
            int fucknum = hash[pos1];
            int fucky = now.dis - abs(fucknum - now.x);
            int id = lower_bound(hash, hash + num, fucknum) - hash;
            vectoriterator1 = lower_bound(mygraph[id].begin(), mygraph[id].end(), NODE(now.y - fucky, -1));
            vectoriterator2 = upper_bound(mygraph[id].begin(), mygraph[id].end(), NODE(now.y + fucky, inf));
            tmpvectoriterator = vectoriterator1;
            for(; vectoriterator1 != vectoriterator2; vectoriterator1++){
                NODE tmp  = *vectoriterator1;
                myque[tail++] = POINT(fucknum, tmp.y, tmp.dis);
                ret++;
            }
            mygraph[id].erase(tmpvectoriterator, vectoriterator2);
        }
    }
    return ret;
}
int main(){
    int testcases = 0;
    while(scanf("%d", &n) != EOF && n){
        init();
        readdata();
        printf("Case #%d:\n", ++testcases);
        for(int i = 0; i < num; i++) {
            sort(mygraph[i].begin(), mygraph[i].end());
        }
        scanf("%d", &m);
        for(int i = 1; i <= m; i++){
            int k;
            scanf("%d", &k);
            int sum = fuckit(k);;
            printf("%d\n", sum);
        }
    }
    return 0;
}


  • 1
    点赞
  • 1
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 1 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

sdj222555

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值