标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4400
3 0 0 0 1 1 2 2 2 2 3 1 2 3 0
Case #1: 1 2 0
/*** hdu4400 STL应用 题目大意:在二维坐标系中给出一些点,每次爆炸一些点,每个点都有一个爆炸半径,在半径内的点会接着爆炸,已经爆炸过的不再爆炸,问每次给定一个爆炸点 能有多少炸弹在此次爆炸。注意:点和点之间的距离为曼哈顿距离,而且有重合的点 解题思路:离散化横坐标,对对于每一个横坐标建立一个vector容器,然后将每个容器里的点从小到大排列,然后从小到大排序横坐标,利用lower_bound查找即可。 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <vector> #include <queue> using namespace std; const int maxn = 110005; const int inf = 2000000005; struct node { int y,dis; node(){} node(int y,int dis) { this->y=y; this->dis=dis; } bool operator <(const node &other)const { if(y==other.y)return dis<other.dis; return y<other.y; } }; vector<node>vec[maxn]; struct point { int x,y,dis; point(){} point(int x,int y,int dis) { this->x=x; this->y=y; this->dis=dis; } }po[maxn]; queue<point>q; int n,m,Hash[maxn]; int main() { int tt=0; while(~scanf("%d",&n)) { if(n==0)break; for(int i=0;i<maxn;i++)///各个容器清空 { vec[i].clear(); } int num=0; for(int i=1;i<=n;i++) { scanf("%d%d%d",&po[i].x,&po[i].y,&po[i].dis); Hash[num++]=po[i].x;///储存所有点的横坐标 } sort(Hash,Hash+num); num=unique(Hash,Hash+num)-Hash;///去重,num为去重后的个数 for(int i=1;i<=n;i++)///对于每个横坐标x视为一个容器 { int id=lower_bound(Hash,Hash+num,po[i].x)-Hash; vec[id].push_back(node(po[i].y,po[i].dis)); } for(int i=0;i<num;i++)///每个横坐标容器排序 { sort(vec[i].begin(),vec[i].end()); } scanf("%d",&m); printf("Case #%d:\n",++tt); for(int i=1;i<=m;i++) { int k,ret=0;; scanf("%d",&k); while(!q.empty())q.pop(); vector<node>::iterator it1,it2,it; q.push(point(po[k].x,po[k].y,po[k].dis)); while(!q.empty()) { point now=q.front(); q.pop(); ///确定可及横坐标范围 int x=lower_bound(Hash,Hash+num,now.x-now.dis)-Hash; int y=upper_bound(Hash,Hash+num,now.x+now.dis)-Hash; for(;x<y;x++) { int t=Hash[x];///t为正在查找的横坐标点 int yy=now.dis-abs(t-now.x);///该横坐标下的纵坐标可及最大值 int id=lower_bound(Hash,Hash+num,t)-Hash; it1=lower_bound(vec[id].begin(),vec[id].end(),node(now.y-yy,-1)); it2=lower_bound(vec[id].begin(),vec[id].end(),node(now.y+yy,inf)); it=it1; for(;it1<it2;it1++) { node tmp=*it1; q.push(point(t,tmp.y,tmp.dis)); ret++; } vec[id].erase(it,it2);///删除已经经历过的点 } } printf("%d\n",ret); } } return 0; }
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/44725727