题目描述
给定一个N位的数,将火柴棍重新排列后,能得到的最大的数是多少?
注意不能多出或者少一位, 火柴棍要全部用上.
输入
第一行整数T,表示数据组数
接下来T行,每行一个整数N, 然后是N位数,表示原来的数,可能会有前导0,中间用空格隔开。
输出
对于每组数据,输出一行,最大的能得到的数是多少。
样例输入
3
1 3
3 512
3 079
样例输出
5
977
997
数据范围限制
对于20%的数据:1 ≤ n ≤ 10
对于60%的数据:1 ≤ n ≤ 1000
对于100%的数据: 1 ≤ n ≤ 100000,1 ≤T≤ 10
分析:这道题一看就知道用贪心。从高位到低位(保证能得到最大的数),从大到小(保证当前所选数最大)。然而光这样是不行的,因为题目规定将火柴棍重新排列后,不能多出或者少一位。所以我们则每次选数后都要进行判断(用花费火柴数最少的和花费火柴数最多的进行限制)
code
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int hzs[10]={6,2,5,5,4,5,6,3,7,6};
int t,n,sum,tt;
char ch;
bool pd(int i,int j) //因为题目规定不能多出或者少一位,所以每选择一个数就要进行判断,判断剩下的全部用2(因为它所用火柴数最少)或8(同理)是否能装的下
{
return i*2<=j&&j<=i*7;
}
int main()
{
//freopen("match.in","r",stdin);
//freopen("match.out","w",stdout);
cin>>t;
while(t--)
{
char x;
sum=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>ch;
sum+=hzs[ch-'0']; //加总所用火柴数
}
for(int i=1;i<=n;i++)
{
tt=9; //因为它说重新排列后数要最大,所以要从9开始
if(i==n) //判断是否是最后一位,如果是最后一位,一定是会被刚刚好sum=0,所以只用找所花火柴数等于sun就可以了!
{
while(sum!=hzs[tt])
--tt;
cout<<tt;
break;
}
while(!pd(n-i,sum-hzs[tt])) //如果不满足条件,就继续往下判断
--tt;
sum-=hzs[tt];
cout<<tt;
}
cout<<endl; //换行
}
return 0; //结束
}