[HNOI2004] BZOJ1208 宠物收养所 set乱搞

本文介绍了一种使用C++实现的宠物与领养人匹配算法。通过一个set数据结构存储宠物或领养人的特征值,并利用迭代器操作进行快速匹配,以最小化匹配距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题走这里

一开始看到这道题的时候

以为是SPLAY的模板题

差点就把SPLAY写出来了

结果一看,你TM直接用set不就行了


本题只需用一个set

其中储存宠物或者领养人的特征值

依题意,不可能同时存在多余的宠物和多余的领养人

因此只需用一个flag标记此时set中是宠物还是领养人即可


每有一个特征值为a的宠物进入而此时有多余领养人(或者相反)时,找出set中a的前驱和后继

后者用lower_bound求出,前者只需将lower_bound返回的迭代器自减即可

要记得各种特判

讲真在这之前我真的不知道迭代器能够--,一直以为只能++,我真是智障


代码如下:

#include <bits/stdc++.h>
#define MOD 1000000
using namespace std;
set<int> s;
int n,t,ret;
int main()
{
	freopen("pet.in","r",stdin);
	freopen("pet.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int t1,t2,l,r;
		scanf("%d%d",&t1,&t2);
		if((t1^(t>0))&&t!=0)
		{
			set<int>::iterator it=s.lower_bound(t2);
			if(it==s.begin())
			{
				l=r=*it;
			}
			else
			{
				if(it==s.end())
				{
					l=r=*(--it);
				}
				else
				{
					r=*it;
					l=*(--it);
				}
			}
			ret=(ret+min(abs(t2-l),abs(t2-r)))%MOD;
			if(abs(t2-l)>=abs(t2-r))
			{
				s.erase(r);
			}
			else
			{
				s.erase(l);
			}
		}
		else
		{
			s.insert(t2);
		}
		if(t1)//领养者 
		{
			t++;
		}
		else//宠物 
		{
			t--;
		}
	}
	cout<<ret<<endl;
	return 0;
}
/*
20
0 586192
0 154341
0 882473
0 822823
0 516300
1 558644
1 127842
1 575969
1 787407
1 236357
1 461443
1 909522
1 307269
1 342303
1 117123
0 177696
0 530631
0 64279
0 659285
0 417888
*/




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值