CF1494C 1D Sokoban(二分+思维)

题目传送门
这道题利用了C++ STL库里面的upper_bound模板(当然也可以手搓)当然也可以使用lower_bound模板,具体的使用请参考大佬博客:
大佬博客传送门
那么这道题关于暴力这件事。。就是分正负两边操作,将a[i]和b[i]重合的地方总和记为初始的答案res,现在把你目前移动的箱子当成一辆火车,每经过一个a[i],我们的火车就多了一节,枚举火车头是所有我们询问的地方,然后求出答案最大的情况。

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
map<int,int>mp;
int input[2102102];
int inask[2102102];
int a[2102102];
int b[2102102];
int solve(int lena,int lenb){
	int count=0;
	mp.clear();
	for(int i=1;i<=lena;i++)	mp[a[i]]=1;
	for(int i=1;i<=lenb;i++)    if(mp[b[i]])count++;
	int res=count;
	int ans=res;
	for(int i=1;i<=lenb;i++){
		if(mp[b[i]]){
			res--;
			continue;
		}
		//为什么continue,那是因为这个位置已经有了,前面的位置是前面求得的最大值,(挪到这里来,所有ab重合的位置一定会小于等于上一回合算出来的ans因此这一局一定要跳过)。
		int pp=upper_bound(a+1,a+1+lena,b[i])-a-1;
		//upper_bound:返回大于这个数的第一个数的迭代器,
		//那么这句话的意思就是
		//把目前正在推的所有箱子的第一个挪到b[i]
		//剩下的目前推的箱子就怼在一起了 
		//也就是看b[i]这前面(包括b[i]这个位置)一共有pp个箱子
		int qq=upper_bound(b+1,b+1+lenb,b[i]-pp)-b;
		//这个意思就是我们的正在推的箱子的头部的位置在
		//b[i]这个位置,尾部的位置在b[i]-pp+1这个位置
		//因此这个位置用lower_bound(b+1,b+1+lenb,b[i]-pp+1)-b;
		//也是可以滴!
		ans=max(ans,res+i-qq+1);
		//这里把res看成一部分这是我们枚举的这个位置之后的所有和
		//a[i]重合的地方的总和,剩下的i-qq+1后面来解释
		//为什么要加1呢,那就是qq是我们刚好有箱子的第一个位置
		//那么前面那个位置是刚好没有的
		//所以我们要+1代表的是多减掉了一个箱子的位置
		//咱们还要把它加回来 
	}
	return ans;
}
int main(){
	int T;
	cin>>T;
	while(T--){
		int n,m;
		int lena=0,lenb=0;
		cin>>n>>m;
		for(int i=1;i<=n;i++){
			cin>>input[i];
			if(input[i]>=0) a[++lena]=input[i];
		}
		for(int i=1;i<=m;i++){
			cin>>inask[i];
			if(inask[i]>=0) b[++lenb]=inask[i];
		}
		int ans=solve(lena,lenb);
		lena=lenb=0;
		for(int i=n;i>=1;i--){
			if(input[i]<0)  a[++lena]=-input[i];
		} 
		for(int i=m;i>=1;i--){
			if(inask[i]<0)  b[++lenb]=-inask[i];
		}
		ans+=solve(lena,lenb);
		cout<<ans<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值