HDU4400 离散化+multiset

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

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

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

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

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

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<queue>
 5 #include<set>
 6 #include<algorithm>
 7 #include<iostream>
 8 #include<math.h>
 9 using namespace std;
10 const int maxn = 100015;
11 int myhash[ maxn ];
12 struct node{
13     int x,y,d;
14 }mine[ maxn ];
15 struct node2{
16     int y,id;
17     node2( int a,int b ){
18         y=a;
19         id=b;
20     }
21     bool operator<( const node2 &tmp ) const 
22     {
23         return y<tmp.y;
24     }
25 };
26 multiset<node2>p[ maxn ];
27 multiset<node2>::iterator LL,RR,it;
28 queue<int>q;
29 bool vis[ maxn ];
30 void init( int cnt ){
31     for( int i=0;i<cnt;i++ )
32         p[ i ].clear();
33     memset( vis,false,sizeof( vis ));
34 }
35 int lisanhua( int n ){
36     sort( myhash,myhash+n );
37     int cnt;
38     cnt=unique( myhash,myhash+n )-myhash;
39     return cnt;
40 }//return the new number
41 int main(){
42     int n;
43     int ca=1;
44     while( scanf("%d",&n)!=EOF,n ){
45         for( int i=0;i<n;i++ ){
46             scanf("%d%d%d",&mine[i].x,&mine[i].y,&mine[i].d);
47             myhash[ i ]=mine[ i ].x;
48         }
49         int cnt=lisanhua( n );
50         init( cnt );
51         for( int i=0;i<n;i++ ){
52             int pos=lower_bound( myhash,myhash+cnt,mine[i].x )-myhash;
53             p[ pos ].insert( node2( mine[i].y,i ));
54         }
55         printf("Case #%d:\n",ca++);
56         int m;
57         scanf("%d",&m);
58         while( m-- ){
59             int id;
60             scanf("%d",&id);
61             id--;
62             if( vis[ id ]==true ){
63                 puts("0");
64                 continue;
65             }
66             while( !q.empty() )
67                 q.pop();
68             int ans=0;
69             q.push( id );
70             vis[ id ]=true;
71             while( !q.empty() ){
72                 int now_id=q.front();
73                 q.pop();
74                 ans++;
75                 int first_pos=lower_bound( myhash,myhash+cnt,mine[ now_id ].x-mine[ now_id ].d )-myhash;
76                 int last_pos=upper_bound( myhash,myhash+cnt,mine[ now_id ].x+mine[ now_id ].d )-myhash;
77                 //首先由横坐标确定大致的 x 寻找范围
78                 for( int pos=first_pos;pos<last_pos;pos++ ){
79                     int dy=mine[ now_id ].d-abs( mine[ now_id ].x-myhash[ pos ] );
80                     LL=p[ pos ].lower_bound( node2( mine[ now_id ].y-dy,0 ) );
81                     RR=p[ pos ].upper_bound( node2( mine[ now_id ].y+dy,0 ) );
82                     //然后再由纵坐标确定 y 的寻找范围
83                     for( it=LL;it!=RR;it++ ){
84                         if( vis[ it->id ]==false ){
85                             vis[ it->id ]=true;
86                             q.push( it->id );
87                         }
88                     }
89                     p[ pos ].erase( LL,RR );//必须删除已经爆炸的点!!!
90                 }
91             }
92             printf("%d\n",ans);
93         }
94     }
95     return 0;
96 }

离散化一直是内伤。。。。。

keep moving...
原文地址:https://www.cnblogs.com/xxx0624/p/2937860.html