AlenaNuna

导航

D Cross Explosion||Toyota Programming Contest 2024#9(AtCoder Beginner Contest 370)

题目:Cross Explosion

题意:给一个矩阵,矩阵元素数小于等于4e5。矩阵初始都是墙体。q次操作,q<=1e5。每次操作在坐标(r,c)处放置一个炸弹,若此处是墙体,则炸毁墙体,否则就造成十字爆炸伤害,炸毁以(r,c)为中心,十字方向第一次碰到的四个墙体(除了碰到边界)。

我一开始想的是线段树维护每行和每列的空隙情况,再二分判断炸毁的墙体位置。但是我不知道怎么开空间,而且感觉代码难度很大T_T

赛后翻了一下别人的代码,发现可以用vector<set<int> >v(n+1)来便捷维护行的情况(列的情况同理),豁然开朗,感觉自己STL还是用得很不熟练啊…> <

用vector<set<int> >v(n+1)来便捷维护行的情况(列的情况同理),以每一行为例,初始set中依次存入1到m,爆炸时1.如果该处有墙体则对应set.find()!=set.end()(行和列都要判断)的情况,然后set.erase()清除该处墙体。2.如果爆炸时该处没有墙体,则利用set.lower_bound()找出右侧第一个墙体,auto it=set.lower_bound();it--;则是左侧第一个墙体。(记得判断边界情况)。同样用set.erase()清除左右的墙体,但是记得清除墙体时同时要维护被清除墙体的列情况。(举例:设被清除墙体坐标为(x,y),那么该墙体被清除后,y列上的x同样需要被erase。我一开始就是忘了这里,还调了好一会儿。)初始答案为n*m,每清除一个墙体就ans--;最后就可以输出ans了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int h,w,q,r,c,ans;
 4 void Work(int x,int y,vector<set<int> >&hang,vector<set<int> >&lie){
 5     if(hang[x].find(y)!=hang[x].end()&&lie[y].find(x)!=lie[y].end()){
 6         hang[x].erase(y);
 7         lie[y].erase(x);
 8         ans--;
 9         return;
10     }
11     auto it=hang[x].lower_bound(y);
12     if(it!=hang[x].end()){
13         hang[x].erase(it);
14         lie[*it].erase(x);
15         ans--;
16     }
17     it=hang[x].lower_bound(y);
18     if(it!=hang[x].begin()){
19         it--;
20         hang[x].erase(it);
21         lie[*it].erase(x);
22         ans--;
23     }
24     it=lie[y].lower_bound(x);
25     if(it!=lie[y].end()){
26         lie[y].erase(it);
27         hang[*it].erase(y);
28         ans--;
29     }
30     it=lie[y].lower_bound(x);
31     if(it!=lie[y].begin()){
32         it--;
33         lie[y].erase(it);
34         hang[*it].erase(y);
35         ans--;
36     }
37     return;
38 }
39 void init(){
40     scanf("%d%d%d",&h,&w,&q);
41     vector<set<int> >hang(h+1);
42     vector<set<int> >lie(w+1);
43     ans=h*w;
44     for(int i=1;i<=h;i++)
45         for(int j=1;j<=w;j++){
46             hang[i].insert(j);
47             lie[j].insert(i);
48         }
49     for(int i=1;i<=q;i++){
50         scanf("%d%d",&r,&c);
51         Work(r,c,hang,lie);
52     }
53     printf("%d\n",ans);
54     return;
55 }
56 int main(){
57     init();
58     return 0;
59 }

 

posted on 2024-09-08 03:30  AlenaNuna  阅读(75)  评论(0编辑  收藏  举报