关于省选A卷T1
  • 板块灌水区
  • 楼主Ink_Render
  • 当前回复14
  • 已保存回复14
  • 发布时间2021/4/10 18:56
  • 上次更新2023/11/5 00:44:55
查看原帖
关于省选A卷T1
151241
Ink_Render楼主2021/4/10 18:56

考场把题目想复杂了……有哪位巨佬帮忙看一下正确性

大体思路是存下每个值的牌编号 idid 和正反面 flagflag (正面为 0 ,反面为 1 ),按照数值排序,双指针从头开始扫,用 t[]存下目前区间内每个编号出现的次数,用一些奇奇怪怪的更改,如果满足条件就计入答案。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
int n,m,sum,k,tail;
ll ans;
int t[N];
struct node
{
	int val,flag,id;
}p[N<<1];
bool cmp(node a,node b) {return (a.val==b.val)?(a.flag<b.flag):(a.val<b.val);}
void add(int x)
{
	if(t[p[x].id]==0)
	{
		sum++;
		k+=(p[x].flag);
	}
	else if(p[x].flag==0) k--;
	t[p[x].id]++;
}
void del(int x)
{
	if(t[p[x].id]==1)
	{
		sum--;
		k-=(p[x].flag);
	}
	else if(p[x].flag==0) k++;
	t[p[x].id]--;
}
int main()
{
	freopen("card.in","r",stdin);
	freopen("card.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&p[i].val);
		p[i].id=i,p[i].flag=0;
	}
	for(int i=n+1;i<=(n<<1);i++)
	{
		scanf("%d",&p[i].val);
		p[i].id=i-n,p[i].flag=1;
	}
	sort(p+1,p+(n<<1)+1,cmp);
	tail=1,ans=2e9;
	for(int i=1;i<=(n<<1);i++)
	{
		add(i);
		while(sum==n || k>m)
		{
			if(sum==n && k<=m) ans=min(ans,1ll*(p[i].val-p[tail].val));	
			del(tail);
			tail++;
		}
	}
	printf("%lld",ans);
	return 0;
}
2021/4/10 18:56
加载中...