标签:
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