问题 F: 火柴棒
时间限制: 1 Sec 内存限制: 128 MB
题目描述
Flag巨巨的桌上有着非常多的火柴棒。这些火柴棒被摆成了一个十进制数。
每个数字字母用火柴棒的摆法如下图。
这个十进制数有n位。某一天,Flag巨巨想把这些火车棒重新排列一次。他喜欢美妙的数字,所以他希望排出的新的数字是一个回文数(如12321,1221都是回文数,1231则不是回文数),并且要恰好用完所有的火柴棒。同时他也喜欢大的数字,所以他希望排出来的新数字要尽量大。现在我们知道火柴棒原本排列的数字,你能求出这些火柴棒能排列出的最大的回文数是什么吗?
输入
第一行给定一个整数T,代表测试数据组数
之后T行每行给定一个n位十进制数(1<=n<=10000),表示火柴棒原本排列的数字。
输出
根据输入数据,每行输出一个十进制数,表示这些火柴棒能排列出的最大的回文数。
样例输入
3248
样例输出
511171
提示
每一个数字所需要的火柴棒数量与题目中的图相符。
对于样例输入,原本排列的数是‘2’,总共有5根火柴棒,可以排列出的最大的回文数为5。
思路: 贪心算法。先字符串处理出全部火柴数,再分类讨论:1.偶数个,全为1;2.奇数个且除以2后仍为奇数,则中间7,两边7,共3个7,其余为1;3.奇数个且除以2后为偶数,则仅中间7,其余为1.
#include <stdio.h>
#include <queue>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <iostream> // C++头文件,C++完全兼容C
#include <algorithm> // C++头文件,C++完全兼容C
#define fre freopen("in.txt","r",stdin) //以文件代替控制台输入,比赛时很常用,能缩短输入测试样例的时间
#define INF 0x3f3f3f3f
#define inf 1e60
using namespace std; // C++头文件,C++完全兼容C
#define N 100005 // 宏定义
#define LL long long //宏定义
char op[N];
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
{
int n,m;
scanf("%s",op);
int k=-1;
m=0;
while(op[++k]!='\0') //每个数相对的火柴数
{
if(op[k]=='0'||op[k]=='6'||op[k]=='9')
m+=6;
else if(op[k]=='2'||op[k]=='3'||op[k]=='5')
m+=5;
else if(op[k]=='1') m+=2;
else if(op[k]=='4') m+=4;
else if(op[k]=='7') m+=3;
else if(op[k]=='8') m+=7;
}
if(m==5){ //特判5
printf("5\n");
continue;
}
int t=m/2;
int ans=m%2;
if(ans==0) //偶数
{
for(int i=0;i<t;i++)
printf("1");
printf("\n");
}
else
{
if(t%2==0) //除以2后为偶数
{
for(int i=1;i<t;i++)
{
if(i==1 || i==(t/2) || i==t-1)
{
printf("7");
}
else
printf("1");
}
printf("\n");
}
else //除以2后为奇数
{
for(int i=1;i<=t;i++)
{
if(i==((t+1)/2))
printf("7");
else
printf("1");
}
printf("\n");
}
}
}
}