考场把题目想复杂了……有哪位巨佬帮忙看一下正确性
大体思路是存下每个值的牌编号 id 和正反面 flag (正面为 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;
}