Time Limit: 3000/1000MS (Java/Others)
Memory Limit: 65535/65535KB (Java/Others)
小帆宝8岁时换了个可爱的小同桌,小同桌非常喜欢8这个数字。一天上课学习完乘法后,小同桌给了帆宝一堆数,问帆宝能不能把它们排成一排,让所有相邻两个数的乘积都为8的倍数呢?
帆宝当然拒绝不了可爱小同桌的要求啦,但是又怕答错呢。机智的你能帮帮他吗?
Input
第一行一个数,表示数字个数
N(N≤100)
第二行有N个数,分别是小同桌给帆宝的第i个数
ai(ai∈(1,2,4,8))
Output
如果能找到满足条件的排列方法,输出”YES”并在第二行输出任意一种方案,如果不能,则输出”NO”。(无双引号,注意大小写)
样例输入1:
4
8 1 1 8
样例输出1:
YES
1 8 8 1
样例输入2:
3
1 2 4
样例输出2:
NO
Source
第九届ACM趣味程序设计竞赛第二场(正式赛)
题解:
构造
对于所有2,4
我们可以形成242424242…..
然后多余的4放在最前面
4444….4444242424242…..
然后对于1,8
181818181……..
然后所有剩余的8放在最后面
1818181….1818888…..888
那么我们只需要看看给定的1,2,4,8的数量是否能够组成形如
4444….44424242424……424242(4)8181818…..818188888….
就行了
#include<bits/stdc++.h>
#define LiangJiaJun main
using namespace std;
int c[14],n,x;
deque<int>ans;
int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&x);
c[x]++;
}
while(c[2]>0){
c[2]--;
ans.push_back(2);
if(c[4]>0){
c[4]--;
ans.push_back(4);
}
else if(c[8]>0){
c[8]--;
ans.push_back(8);
}
else if(c[2]||c[1])return puts("NO"),0;
}
while(c[4]>0){
c[4]--;
ans.push_front(4);
}
if(!ans.empty()&&ans.back()!=8){
ans.push_back(8);
if(c[8])c[8]--;
else if(c[1]>0)return puts("NO"),0;
}
while(c[1]>0){
c[1]--;
ans.push_back(1);
if(c[8]>0){
c[8]--;
ans.push_back(8);
}
else if(c[1]>0)return puts("NO"),0;
}
while(c[8]>0){
c[8]--;
ans.push_back(8);
}
puts("YES");
while(!ans.empty()){
printf("%d ",ans.front());
ans.pop_front();
}
puts("");
return 0;
}