题意
给你 0 , 1 , 2 , 3 0,1,2,3 0,1,2,3的数量,组成一个序列,相邻差为 1 1 1。
题解
⋅
·
⋅ 如果我们令
0
0
0开头,则有
0101010101
0101010101
0101010101,结尾一定是
1
1
1(如果有
2
、
3
2、3
2、3的话)再接
2121212
2121212
2121212,结尾一定是
2
2
2(如果有
3
3
3的话)
⋅
·
⋅ 如果我们令
1
1
1开头,则有
1010101
1010101
1010101,结尾同上,接上
2121212
2121212
2121212,再接
323232
32 3232
323232。
⋅
·
⋅ 一般来说这两种情况就可以涵盖完了,但是不存在
0
、
1
0、1
0、1或不存在
0
0
0的时候,就需要用到
2
2
2开头和
3
3
3开头了。令
2
2
2开头,首先
2121212
2121212
2121212(如果有
3
3
3必须以
2
2
2为结尾,否则
1
1
1也可以)。然后接
3232323
3232323
3232323
⋅
·
⋅ 令
3
3
3开头就只有
3232323232
3232323232
3232323232,如果有
1
1
1就接上
121212
121212
121212。一般是没有
0
0
0的,如果有前面情况就可以解决了。
我们分析的过程中发现这四种情况其实都是尽可能先走小的,再以自己为结尾接上更大。(判断就直接先小后大)即可。
反之。先大后小,同理也可,先走大的,再以自己为结尾走小的,但是一会走大一会走小绝对不可以。可是一个贪心问题。
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int cnt[5],A[5];
vector<int>G;
int main(){
cin>>cnt[0]>>cnt[1]>>cnt[2]>>cnt[3];
int n=cnt[0]+cnt[1]+cnt[2]+cnt[3];
for(int i=0;i<4;i++){
G.clear();
if(cnt[i]==0)continue;
for(int j=0;j<4;j++)A[j]=cnt[j]-(j==i);
G.push_back(i);
bool ok=true;
for(int i=1;i<n;i++){
int p=G[i-1];
if(p-1>=0&&A[p-1])G.push_back(p-1),A[p-1]--;
else if(p+1<4&&A[p+1])G.push_back(p+1),A[p+1]--;
else{
ok=false;
break;
}
}
if(ok){
puts("YES");
for(auto u:G)cout<<u<<" ";
return 0;
}
}
puts("NO");
}