1980: 赛前的准备--火柴棒
Description
小明在收拾机房的时候发现黑板上有这样一个由火柴棍组成的数字
小明想到可以将这个火柴棍组成的数字拆分,然后重新拼成一个可以组成的最大的回文数(例如1221,1771是回文数,1234不是回文数)。每个数字需要的火柴棍数量如图所示。 现在给你一个由火柴棍组组成的数, 你知道将它拆分和重组后可以变成的回文数最大是多少吗?
![](https://acm.zzuli.edu.cn/zzuliacm/upload/201612/1.png)
Input
第一行给定一个整数T,代表T组测试数据
每组测试数据给定一个十进制数, 长度范围为[1,10000],表示火柴棒原本排列的数字。
Output
根据输入数据,每行输出一个十进制数,表示这些火柴棒能排列出的最大的回文数。
Sample Input
3
2
4
8
Sample Output
5
11
171
HINT
每一个数字所需要的火柴棒数量与题目中的图相符。
对于样例输入,原本排列的数是‘2’,总共有5根火柴棒,可以排列出的最大的回文数为5。
思路:(弱鸡博主......)
第一步:把各个数字对应的木棒列出来,发现2,3,5木棒相同,0,6,9木棒相同,则0,2,3,6输出时可以舍去,用5,9即可;
第二步:仔细思考,你会发现前几个特例外,当木棒数量大于10时,输出时只需要用到1和7,其余用不到;
第三步:分出奇偶,当 sum 是偶数输出全是1,奇数分情况决定输出时是几个7,且7的数量一定是奇数;
第四步:当 sum 是奇数时,输出至少有一个7,然后减去组成7的这三个木棒,看剩下的木棒是否能组成回文数式的1;
第五步:如果能,输出时中间的是7,格式为 11...11711...11 ,如果不能,格式 711...11711...117;
#include<stdio.h>
#include<string.h>
char a[10000+100];//由于输入长度较大,字符存储;
int main()
{
int t;
scanf("%d",&t);
getchar();
while(t--)
{
int p,i,k,sum=0;
scanf("%s",a);
int len=strlen(a);
for(i=0;i<len;i++)//计算火柴棍总和(int即可)sum;
{
if(a[i]=='0' || a[i]=='6' || a[i]=='9')
{
sum+=6;
}
if(a[i]=='2'|| a[i]=='3' || a[i]=='5')
{
sum+=5;
}
if(a[i]=='1')
{
sum+=2;
}
if(a[i]=='4')
{
sum+=4;
}
if(a[i]=='7')
{
sum+=3;
}
if(a[i]=='8')
{
sum+=7;
}
}
if(sum%2==0)//剪去较为简单的偶数;
{
for(i=0;i<sum/2;i++)
{
printf("1");
}
}
else if(sum==3)//把前几个奇葩的枚举;
{
printf("7");
}
else if(sum==5)
{
printf("5");
}
else if(sum==7)
{
printf("171");
}
else if(sum==9)
{
printf("777");
}
else//问题的难点;
{
k=(sum-3)/2;//3代表组合'7'需要的火柴;
p=k%2;// 判断除去三个木棒后,是否剩余的全部能组成回文数的'1';
if(p==0)//格式 11...11711...11;
{
for(i=0;i<sum/2;i++)
{
if(i==sum/4)
{
printf("7");
continue;
}
printf("1");
}
}
else//格式 711...11711...117 ;
{
k=sum/2-1;
for(i=0;i<k;i++)
{
if(i==0 || i==k/2 || i==k-1)
{
printf("7");
continue;
}
printf("1");
}
}
}
printf("\n");
}
return 0;
}