[Codeforces 26E] MultiThreading

Brief Intro:

给你n个数,每个数有2*CNT[i]个,让你构造一个序列

使得最终的Y值为W(其余见题面)

Solution:

就是一道纯构造的题目:

先把特殊情况特殊处理,接下来考虑一般情况:

如果让每种数字都连续放置,则对于每两个相同的A[i],Y则加一

要想最终Y=W,则要将多余的去除。于是这样构造:

A:1........1211...112  B:11..122..233...344...4.....nn

最终序列分为A段和B段,其中A段仅能使Y+=2,同时去除多余的项

剩余的先计算好后在B中连续放置即可

Code:

#include <bits/stdc++.h>

using namespace std;

template<class T> inline void putnum(T x)
{
    if(x<0)putchar('-'),x=-x;
    register short a[20]={},sz=0;
    while(x)a[sz++]=x%10,x/=10;
    if(sz==0)putchar('0');
    for(int i=sz-1;i>=0;i--)putchar('0'+a[i]);
    putchar(' ');
}

int n,w,dat[1005],res[1005],sum=0,pos=-1;

int main()
{
    cin >> n >> w;
    for(int i=1;i<=n;i++)
    {
        cin >> dat[i],sum+=dat[i];
        if(dat[i]==1) pos=i;
    }
    
    if(w<1 || w>sum || (n==1 && w!=sum) || (w==1 && pos==-1))
        return puts("No"),0;
    puts("Yes");
    
    if(n==1)
        for(int i=1;i<=2*dat[1];i++) putnum(1);
    else if(w==1)
    {
        dat[pos]--;
        putnum(pos);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=2*dat[i];j++)
                putnum(i);
        putnum(pos);
    }
    else
    {
        w=w-2;dat[1]--;dat[2]--;
        for(int i=1;i<=n;i++)
            while(w && dat[i])
                res[i]++,w--,dat[i]--;
        putnum(1);
        for(int i=2;i<=n;i++)
            for(int j=1;j<=2*dat[i];j++)
                putnum(i);
        putnum(1);putnum(2);
        for(int i=1;i<=2*dat[1];i++) putnum(1);
        putnum(2);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=2*res[i];j++)
                putnum(i);
    }
    return 0;
}

Review:

对于构造题,要利用性质去除不符合条件的项

猜你喜欢

转载自www.cnblogs.com/newera/p/9085886.html