题意:给
n
种珠子,第
题解:构造。
分一下几种情况:
1)若珠子个数为奇数个的种类大于1,则方案数为0。随意输出。
2)
ans=gcd(a1,a2....an)
再将珠子平分为ans份。在每份中若珠子个数为奇数个的种类大于1,则将两份合并成一份。每份将珠子对称放。放
n
<script type="math/tex" id="MathJax-Element-699">n</script>份。最后输出。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[30],n;
int b[101000];
int gcd(int x,int y)
{return y?gcd(y,x%y):x;}
int main()
{
cin >> n;
int ans = 0,cnt = 0;
for (int i = 1;i <= n;i++) cin >> a[i];
for (int i = 1;i <= n;i++) ans = gcd(ans,a[i]);
for (int i = 1;i <= n;i++) cnt += a[i]&1;
if (cnt > 1)
{
cout << 0 << endl;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= a[i];j++)
printf("%c",'a'+i-1);
printf("\n");
return 0;
}
cnt = 0;
for (int i = 1;i <= n;i++) a[i]/=ans,cnt+=a[i]&1;
cout << ans << endl;
if (cnt > 1)
{
ans /=2;for (int i = 1;i <= n;i++) a[i]*=2;
}
int m = 0;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= a[i];j++)
m++;
int l = 1,r = m;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= a[i]/2;j++)
b[l++]=i,b[r--]=i;
for (int i = 1;i <= n;i++)
if (a[i]&1) b[l++]=i;
while (ans--)
for (int i = 1;i <= m;i++)
printf("%c",b[i]+'a'-1);
}