hdu 4400 Mines(离散化+bfs+枚举)

Problem Description

Terrorists put some mines in a crowded square recently. The police evacuate all people in time before any mine explodes. Now the police want all the mines be ignited. The police will take many operations to do the job. In each operation, the police will ignite one mine. Every mine has its "power distance". When a mine explodes, any other mine within the power distance of the exploding mine will also explode. Please NOTE that the distance is Manhattan distance here.

More specifically, we put the mines in the Cartesian coordinate system. Each mine has position (x,y) and power distance d.

The police want you to write a program and calculate the result of each operation.

Input

There are several test cases.
In each test case:
Line 1: an integer N, indicating that there are N mines. All mines are numbered from 1 to N.
Line 2…N+1: There are 3 integers in Line i+1 (i starts from 1). They are the i-th mine’s position (xi,yi) and its power distance di. There can be more than one mine in the same point.
Line N+2: an integer M, representing the number of operations.
Line N+3...N+M+2 : Each line represents an operation by an integer k meaning that in this operation, the k-th mine will be ignited. It is possible to ignite a mine which has already exploded, but it will have no effect.

1<=M<=N<=100000,0<=xi,yi<=10^9,0<=di<=10^9

Input ends with N=0.

Output

For each test case, you should print ‘Case #X:’ at first, which X is the case number starting from 1. Then you print M lines, each line has an integer representing the number of mines explode in the correspondent operation.

Sample Input

3
0 0 0
1 1 2
2 2 2
3
1
2
3
0

Sample Output

Case #1:
1
2
0

Source

2012 ACM/ICPC Asia Regional Jinhua Online

题意:引爆一个炸弹会同时引爆与它相距d的炸弹

重点:由于x,y坐标的范围很大,所以必须离散化,显而易见。在这里可以利用sort+unique进行离散化并存储在myhash中。

其次由于一个点可能多次放炸弹,但只有一次有效,所以用一个vis数组记录

所以对于任意一个炸弹(x,y,d)。首先由x-d,x+d在myhash中确定y在set的范围first_pos,last_pos

然后 再在set中按照y的范围寻找。。。

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<math.h>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<set>
10 #include<bitset>
11 #include<map>
12 #include<vector>
13 #include<stdlib.h>
14 using namespace std;
15 #define ll long long
16 #define eps 1e-10
17 #define MOD 1000000007
18 #define N 100006
19 #define inf 1e12
20 int n,m;
21 struct Node{
22     int x,y,d;
23 }point[N];
24 int X[N];
25 struct Node2{
26     int y,id;
27     Node2(int a,int b):y(a),id(b){}
28     friend bool operator < (Node2 a,Node2 b){
29         return a.y<b.y;
30     }
31
32 };
33 multiset<Node2>mt[N];
34 int vis[N];
35 int main()
36 {
37     int ac=0;
38     while(scanf("%d",&n)==1 && n){
39         for(int i=0;i<n;i++){
40             scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].d);
41             X[i]=point[i].x;
42         }
43         sort(X,X+n);
44         int ng=unique(X,X+n)-X;
45         for(int i=0;i<N;i++) mt[i].clear();
46         for(int i=0;i<n;i++){
47             int wx=lower_bound(X,X+ng,point[i].x)-X;
48             mt[wx].insert(Node2(point[i].y,i));
49         }
50
51         memset(vis,0,sizeof(vis));
52         printf("Case #%d:\n",++ac);
53         scanf("%d",&m);
54         for(int u=0;u<m;u++){
55             int k;
56             scanf("%d",&k);
57             k--;
58             if(vis[k]){
59                 printf("0\n");
60                 continue;
61             }
62             multiset<Node2>::iterator ly,ry,it;
63             queue<int>q;
64             q.push(k);
65             int ans=0;
66             vis[k]=1;
67             while(!q.empty()){
68                 ans++;
69                 int t1=q.front();
70                 q.pop();
71
72                 int l=lower_bound(X,X+ng,point[t1].x-point[t1].d)-X;
73                 int r=upper_bound(X,X+ng,point[t1].x+point[t1].d)-X;
74                 for(int i=l;i<r;i++){
75                     int dy=point[t1].d-abs(point[t1].x-X[i]);
76                     ly=mt[i].lower_bound(Node2(point[t1].y-dy,0));
77                     ry=mt[i].upper_bound(Node2(point[t1].y+dy,0));
78                     for(it=ly;it!=ry;it++){
79                         if(vis[it->id]){
80                             continue;
81                         }
82                         vis[it->id]=1;
83                         q.push(it->id);
84                     }
85                     mt[i].erase(ly,ry);
86                 }
87             }
88             printf("%d\n",ans);
89
90         }
91
92     }
93     return 0;
94 }

时间: 2024-10-17 04:17:17

hdu 4400 Mines(离散化+bfs+枚举)的相关文章

[ An Ac a Day ^_^ ] hdu 5925 Coconuts 离散化+BFS求连通块

东北赛根本就没看懂的的题目…… 也用到了离散化 1e9的x y范围 200个坏点 很典型的离散化数据范围 还是不太为什么离散化的遍历下标都要从1开始…… 所以说只做这道题对离散化的理解还不是很深刻…… 因为可能换一道题又不会了 还是要多做啊 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(x) cerr<<#x<<"=="<<

hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1110    Accepted Submission(s): 280 Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all peo

HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 524    Accepted Submission(s): 151 Problem Description TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams abou

HDU 1973 Prime path(BFS+素数表)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1973 题目大意:给定两个四位素数a  b,要求把a变换到b变换的过程要保证  每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数 与前一步得到的素数  只能有一个位不同,而且每步得到的素数都不能重复.求从a到b最少需要的变换次数.无法变换则输出Impossible. 如下面的样例:1033 8179 1033 1733 3733 3739 3779 8779 8179 所以答案为6.

hdu 4309 Seikimatsu Occult Tonneru 枚举+最大流

http://blog.csdn.net/julyana_lin/article/details/8070949 题意: n个点,每个点有初始的值 ,三种 通道,1.隧道:可以用来躲避,有固定的容量,也可以用来传递.2.普通的道路,可以无限的通过.3.桥(最多有12座):不花费的话能通过一人,修之后可以无限通过.问最少花费最大可以隐藏人数. 解: 网络流 + 枚举 官方题解: 先不考虑可以修复的桥的性质,则可以将模型简化为n个点的人通过有通过人数上限的有向边,到达一些有人数上限的特殊的边(隧道)

hdu 1429 状压bfs

#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __in

HDU 1242 Rescue(优先队列+bfs)

题目地址:HDU 1242 这个题相比于普通的bfs有个特殊的地方,经过士兵时会额外消耗时间,也就是说此时最先搜到的时候不一定是用时最短的了.需要全部搜一遍才可以.这时候优先队列的好处就显现出来了.利用优先队列,可以让队列中的元素按时间排序,让先出来的总是时间短的,这样的话,最先搜到的一定是时间短的,就不用全部搜一遍了.PS:我是为了学优先队列做的这题..不是为了这题而现学的优先队列.. 代码如下: #include <iostream> #include <stdio.h> #i

hdu 4430 Yukari&#39;s Birthday 枚举+二分

注意会超long long 开i次根号方法,te=(ll)pow(n,1.0/i); Yukari's Birthday Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3262    Accepted Submission(s): 695 Problem Description Today is Yukari's n-th birt

POJ 2243 || HDU 1372:Knight Moves(BFS)

Knight Moves Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11223 Accepted: 6331 Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visit