c. rooks defenders

题意:有两个操作,1是将车放入x,y,2是将x,y里的车删除,3是询问x1,y1,x2,y2里是不是所有的格子都被车攻击,车可以攻击他所在的一行和一列。

思路:想判断相应的行和列有没有被车攻击,我们就判断大于x1和x2的没有车的地方的行和列x和y,如果x小于x2说明有行没覆盖,如果y小于y1说明有列没有被覆盖,行和列相交肯定有一个格子没有覆盖,所以我们就按2这个来判断输出yes或no。被我们用两个set数组a,b分别来存没有被车攻击的行和列,初始时所有的都没有被攻击就把1-n的数全加入set里,然后用两个数组h,w分别来记录行和列上分别有几辆车,当进行操作1的时候我们放车,如果放的行和列上没有车的话,我们就对应的行和列在set里删除,h,w分别加。当进行2操作的时候,h,w分别减,再判断h,w是不是0,如果是的话说明没有车在相对应的行和列,将相对应的行和列加入set里。在进行操作3的时候,我们判断set数组a,b大于等于x1和y1的数,拿他们两个和x2,y2比较,如果有一个大说明有一行或一列全被车覆盖,输出yes,否则输出no。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
int n,q;
const int N=200010;
long long h[N],w[N];
set<int> a,b;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=n+7;i++){
		a.insert(i);
		b.insert(i);  
	}
	int t;
	while(q--){
		cin>>t;
		int x,y,x1,y1,x2,y2;
		if(t==1){
			cin>>x>>y;
			if(h[x]==0){
				a.erase(x); 
			}
			if(w[y]==0){
				b.erase(y); 
			}
			h[x]++;
			w[y]++;
		}else if(t==2){
			cin>>x>>y;
			h[x]--;
			w[y]--;
			if(h[x]==0){
				a.insert(x); 
			}
			if(w[y]==0){
				b.insert(y); 
			}
		}else{
			cin>>x1>>y1>>x2>>y2;
			x=*a.lower_bound(x1);
			y=*b.lower_bound(y1);
			if(x>x2||y>y2){
				cout<<"Yes"<<'\n';
			}else  cout<<"No"<<'\n';
		}
	}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值