6843. 【2020.11.02提高组模拟】移形换影
题目大意
给你一个以0,1,2组成的序列,其中仅有1可以与相邻的数交换,操作次数最多k次,求字典序最小的序列
Solution
考虑贪心
因为0,2的相对位置是不会变的,而1之间的相对位置也是没必要变的
所以把0,2用一个数组储存,1用一个数组储存
贪心放最小的
要注意可能不合法,此时就要选大一点的
Code
#include <cstdio>
#include <algorithm>
#define N 1000001
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int n,i,tot,tmp,l,r,ans[N],p[N],q[N],a[N];
long long k;
void tx(int b[N],int c[N],int &x,int &y)
{
int o=max(0,b[x]-ans[0]);
if (o<=k)
{
k-=o;
ans[ans[0]++]=a[b[x++]];
}else ans[ans[0]++]=a[c[y++]];
}
int main()
{
open("mobiliarbus");
scanf("%d%lld",&n,&k);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if (a[i]==1) q[++tot]=i;else p[++tmp]=i;
}
l=r=ans[0]=1;
for (i=1;i<=n;i++)
{
if (l>tot || r>tmp) break;
if (a[q[l]]<a[p[r]]) tx(q,p,l,r);else tx(p,q,r,l);
}
for (i=l;i<=tot;i++)
ans[ans[0]++]=a[q[i]];
for (i=r;i<=tmp;i++)
ans[ans[0]++]=a[p[i]];
for (i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}