6843. 【2020.11.02提高组模拟】移形换影

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;
}
posted @ 2020-11-04 22:17  Sport_River  阅读(200)  评论(0编辑  收藏  举报