题意:给你一些物体的坐标,给你炸弹,炸弹可以炸一行或一列(输入规定),问你每一颗炸弹可以炸多少个物体(一个物体被炸一次就没了)。
想法:想法很简单,直接模拟,怎么模拟是一个问题,如果用for那是会超时的。
使用map+set(multiset:里面的元素可以重复,而set不可以),map<a,b>(其中a,b为数据类型)这样就形成了一对一的对应关系,但是这个题目是一行对这一行里面的所有的物体,显然是一对多,那么久可以用一个set来代替第二个类型。每次爆炸之后,删除这一行的所有物体就好了,同时列的一些物体也要删除,因为是两个方向的爆炸,所以这样是必要的。
#include<iostream> #include<cstring> #include<cstdio> #include<map> #include<set> using namespace std; map<int,multiset<int> >mx,my; multiset<int>::iterator iter; int n,m; void Input() { mx.clear(); my.clear(); for(int i=1;i<=n;i++) { int a,b; scanf("%d%d",&a,&b); mx[a].insert(b); my[b].insert(a); } } void treatment() { int ans; for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); if(!a) { ans=mx[b].size();//这一行炸弹的个数 for(iter=mx[b].begin();iter!=mx[b].end();iter++) {//找出这一行的炸弹所在的列 my[*iter].erase(b);//这一列的炸弹在b行消失(爆炸) } mx[b].clear();//这一行被炸完了 } else { ans=my[b].size(); for(iter=my[b].begin();iter!=my[b].end();iter++) { mx[*iter].erase(b); } my[b].clear(); } printf("%d\n",ans); } printf("\n"); } int main() { while(~scanf("%d%d",&n,&m),m+n) { Input(); treatment(); } return 0; }