看完包懂,不懂就多看几遍
https://blog.nowcoder.net/kristina1q
题目分析:通过输入0~9的数字个数将他们组成回文数,要求输出最小的回文数,并且去除前导0,如果不存在这样的数字,就返回-1
个人思路:
不管数最后怎样,先找到它,再进行条件筛除(包括前导0和其他条件),先按从小到大的顺序进行放入,然后将0与里面的元素交换,这样可以避免很多讨论(想到string的insert但是不会用,所以改成这种写法)可恶,马上给它学了
容易想到总数的奇偶情况分开讨论比较简单
预处理:
int a[10],ans=0,qi=0,ou=0,now=0;
for(int i=0;i<10;i++)
{
scanf("%d",&a[i]);
ans+=a[i]; //记录总个数
if(a[i]%2==0)ou++; //记录偶数个数
else qi++; //记录奇数个数
}
char *b=new char [ans]; //动态分配总个数个字符空间
for(int i=0;i<ans;i++)
{
b[i]='0';
}
奇:这些数中至多有一个数的个数为奇数
偶:这些数的个数必须都是偶数
上面的讨论已经可以排除一部分情况了,接下来开始寻找
对于偶:
if(ans%2==0) //总数为偶数情况
{
if(qi>0)printf("-1"); //不能有奇数
else
{
int d=a[0]/2; //需要交换0的次数
for(int i=0;i<10;i++) //从小到大放入元素
{
while(a[i]>0)
{
b[now]=b[ans-1-now]=i+48;
now++;
a[i]-=2;
}
}
while(d>0)
{
swap(b[d-1],b[d]); //交换前面的0
swap(b[ans-d],b[ans-d-1]); //交换后面的0
d--;
}
if(b[0]=='0')printf("-1"); //如果有前导0,则输出-1
else //打印
{
for(int i=0;i<ans;i++)
{
printf("%c",b[i]);
}
}
}
}
对于奇:
else
{
if(qi>1)printf("-1"); //至多有一个奇数
else
{
if(a[0]==1&&ans==1) //判断只有1个0的特殊情况
{
printf("0");
}
else
{
int d=a[0]/2;
for(int i=0;i<10;i++)
{
while(a[i]>=2) //存入数据
{
b[now]=b[ans-1-now]=i+48;
now++;
a[i]-=2;
}
for(int i=0;i<10;i++) //判断那一个奇数并放在最中间
{
if(a[i]==1)
{
b[ans/2]=i+48;
break;
}
}
}
while(d>0) //交换0的位置
{
swap(b[ans-d],b[ans-d-1]);
swap(b[d-1],b[d]);
d--;
}
if(b[0]=='0')printf("-1"); //判断是否是前导0
else
{
for(int i=0;i<ans;i++) //打印数组
{
printf("%c",b[i]);
}
}
}
}
}
return 0;